Python SQL查询字符串格式

sso*_*ler 79 python sql string-formatting

我正在尝试找到格式化SQL查询字符串的最佳方法.当我调试我的应用程序时,我想记录所有sql查询字符串,并且正确格式化字符串很重要.

选项1

def myquery():
    sql = "select field1, field2, field3, field4 from table where condition1=1 and condition2=2"
    con = mymodule.get_connection()
    ...
Run Code Online (Sandbox Code Playgroud)
  • 这适用于打印sql字符串.
  • 如果字符串很长并且不符合80个字符的标准宽度,则不是一个好的解决方案.

选项2

def query():
    sql = """
        select field1, field2, field3, field4
        from table
        where condition1=1
        and condition2=2"""
    con = mymodule.get_connection()
    ...
Run Code Online (Sandbox Code Playgroud)
  • 这里的代码很清楚,但是当你打印sql查询字符串时,你会得到所有这些烦人的空白区域.

    从表\n _ ___ 选择field1,field2,field3,field4 \n_ _ ___ ,其中condition1 = 1 \n _ ___ _和 condition2 = 2'

注意:我已经用下划线替换了空格_,因为它们是由编辑器修剪的

选项3

def query():
    sql = """select field1, field2, field3, field4
from table
where condition1=1
and condition2=2"""
    con = mymodule.get_connection()
    ...
Run Code Online (Sandbox Code Playgroud)
  • 我不喜欢这个选项,因为它打破了列表良好的代码的清晰度.

选项4

def query():
    sql = "select field1, field2, field3, field4 " \
          "from table " \
          "where condition1=1 " \
          "and condition2=2 "
    con = mymodule.get_connection()    
    ...
Run Code Online (Sandbox Code Playgroud)
  • 我不喜欢这个选项,因为每行都有额外的输入,并且很难编辑查询.

对我来说,最好的解决方案是选项2,但是当我打印sql字符串时,我不喜欢额外的空格.

你知道其他任何选择吗?

use*_*028 115

很抱歉发布到这样一个老线程 - 但作为一个对pythonic'最佳'有共同兴趣的人,我想我会分享我们的解决方案.

解决方案是使用python的String Literal Concatenation(http://docs.python.org/)构建SQL语句,它可以在Option 2和Option 4之间的某个位置进行限定

代码示例:

sql = ('select field1, field2, field3, field4 '
       'from table '
       'where condition1=1 '
       'and condition2=2 ')
Run Code Online (Sandbox Code Playgroud)

优点:

  1. 它保留了pythonic'well wellulated'格式,但不添加无关的空格字符(污染日志记录).
  2. 它避免了选项4的反斜杠延续丑陋,这使得很难添加语句(更不用说白空间盲).
  3. 而且,在VIM中扩展语句非常简单(只需将光标定位到插入点,然后按SHIFT-O打开一个新行).

  • 如果这是用于打印,我认为更好的替代方法是将其写为带有 `"""` 的多行字符串,并在输出之前使用 `textwrap.dedent()` (4认同)
  • 我们是否不应该始终使用双引号“ SQL查询”来避免弄乱SQL字符串(标准使用单引号)? (3认同)
  • 这是一个旧线程,但我一直在使用这种格式作为最佳实践,但是查询时间较长会变得乏味 (2认同)
  • 如何格式化源代码是一个有效的问题,但在 SQL 上下文中,确实应该突出地提到变量的正确转义更为重要。使用字符串格式准备 SQL 语句*不安全*。 (2认同)

cdl*_*dlk 17

您显然已经考虑了很多编写SQL的方法,以便打印出来,但是如何更改用于调试日志记录的"print"语句,而不是以您不喜欢的方式编写SQL?使用上面您喜欢的选项,如下所示的日志记录功能如何:

def debugLogSQL(sql):
     print ' '.join([line.strip() for line in sql.splitlines()]).strip()

sql = """
    select field1, field2, field3, field4
    from table"""
if debug:
    debugLogSQL(sql)
Run Code Online (Sandbox Code Playgroud)

如果行超过您想要的长度,这也会使得添加额外的逻辑以将记录的字符串分成多行而变得微不足道.


aan*_*dis 13

我遇到的最简洁的方式是受到sql style guide 的启发。

sql = """
    SELECT field1, field2, field3, field4
      FROM table
     WHERE condition1 = 1
       AND condition2 = 2;
"""
Run Code Online (Sandbox Code Playgroud)

本质上,子句开头的关键字应该右对齐,字段名称等应该左对齐。这看起来非常整洁,也更容易调试。


Faz*_*Sap 11

使用“sqlparse”库我们可以格式化 sql。

>>> import sqlparse
>>> raw = 'select * from foo; select * from bar;'
>>> print(sqlparse.format(raw, reindent=True, keyword_case='upper'))
SELECT *
FROM foo;

SELECT *
FROM bar;
Run Code Online (Sandbox Code Playgroud)

参考:https: //pypi.org/project/sqlparse/


Mik*_*tty 7

您可以使用它inspect.cleandoc来很好地格式化打印的 SQL 语句。

这非常适合您的选项 2

注意:print("-"*40)如果您不使用 cleandoc,这只是为了演示多余的空行。

from inspect import cleandoc
def query():
    sql = """
        select field1, field2, field3, field4
        from table
        where condition1=1
        and condition2=2
    """

    print("-"*40)
    print(sql)
    print("-"*40)
    print(cleandoc(sql))
    print("-"*40)

query()
Run Code Online (Sandbox Code Playgroud)

输出:

----------------------------------------

        select field1, field2, field3, field4
        from table
        where condition1=1
        and condition2=2

----------------------------------------
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2
----------------------------------------
Run Code Online (Sandbox Code Playgroud)

来自文档

检查.cleandoc(doc)

清理文档字符串中的缩进,这些文档字符串缩进为与代码块对齐。

从第一行中删除所有前导空格。任何可以从第二行开始统一删除的前导空格都将被删除。随后删除开头和结尾的空行。此外,所有选项卡都扩展为空格。


pan*_*ang 5

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1={} "
       "and condition2={}").format(1, 2)

Output: 'select field1, field2, field3, field4 from table 
         where condition1=1 and condition2=2'
Run Code Online (Sandbox Code Playgroud)

如果条件的值应该是一个字符串,你可以这样做:

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1='{0}' "
       "and condition2='{1}'").format('2016-10-12', '2017-10-12')

Output: "select field1, field2, field3, field4 from table where
         condition1='2016-10-12' and condition2='2017-10-12'"
Run Code Online (Sandbox Code Playgroud)

  • 请永远不要这样做。这就是所谓的 SQL 注入,它非常危险。几乎每个 Python 数据库库都提供了使用参数的工具。如果您发现自己对 SQL 字符串使用了“format()”,那么这是一个主要的代码味道。 (14认同)