Python SQL查询string格式

我试图find格式化SQL查询string的最佳方法。 当我debugging我的应用程序时,我想logging所有的sql查询string,重要的是string正确格式化。

选项1

def myquery(): sql = "select field1, field2, field3, field4 from table where condition1=1 and condition2=2" con = mymodule.get_connection() ... 
  • 这对于打印sqlstring很有用。
  • 如果string很长并且不符合80个字符的标准宽度,那么这不是一个好的解决scheme。

选项2

 def query(): sql = """ select field1, field2, field3, field4 from table where condition1=1 and condition2=2""" con = mymodule.get_connection() ... 
  • 这里的代码是清楚的,但是当你打印sql查询string,你会得到所有这些烦人的空白。

    u'\ n从表中selectfield1,field2,field3,field4 \ n_ _ ___ \ n 其中condition1 = 1 \ n _ ___ _and condition2 = 2'

注:我用下划线_replace了空格,因为它们被编辑器修剪掉了

选项3

 def query(): sql = """select field1, field2, field3, field4 from table where condition1=1 and condition2=2""" con = mymodule.get_connection() ... 
  • 我不喜欢这个选项,因为它打破了明确的表格代码。

选项4

 def query(): sql = "select field1, field2, field3, field4 " \ "from table " \ "where condition1=1 " \ "and condition2=2 " con = mymodule.get_connection() ... 
  • 我不喜欢这个选项,因为所有额外的input在每一行中,也很难编辑查询。

对我来说最好的解决scheme是选项2,但我不喜欢额外的空格,当我打印的SQLstring。

你知道其他的select吗?

对不起,张贴到这样一个古老的线程 – 但作为一个谁也分享了Pythonic“最好”的热情,我想我会分享我们的解决scheme。

解决scheme是使用python的string文字串联( http://docs.python.org/ )来构buildSQL语句,这可以在选项2和选项4之间进行限定

代码示例:

 sql = ('select field1, field2, field3, field4 ' 'from table ' 'where condition1=1 ' 'and condition2=2 ') 

优点:

  1. 它保留pythonic“好的表格”格式,但不会添加无关的空格字符(污染日志)。
  2. 它避免了选项4的反斜杠延续性,这使得添加语句变得困难(更不用说空白失明了)。
  3. 此外,在VIM中展开语句非常简单(只需将光标定位到插入点,然后按SHIFT-O打开一个新行)。

你显然已经考虑了很多写SQL的方法,这样可以打印出来,但是如何改变用于debugging日志的“print”语句,而不是用你不喜欢的方式来编写SQL呢? 使用上面你最喜欢的选项,如何这样的日志loggingfunction:

 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) 

如果行长度超过所需的长度,这也会使添加额外的逻辑来分割跨越多行的loggingstring变得微不足道。

 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' 

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

 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'" 

我碰到的最干净的方式是由SQL风格指南启发。

 sql = """ SELECT field1, field2, field3, field4 FROM table WHERE condition1 = 1 AND condition2 = 2; """ 

从本质上讲,开始一个子句的关键字应该是右alignment的,字段名称等应该保持alignment。 这看起来非常整齐,也更容易debugging。

您可以将字段名称放入数组“字段”中,然后:

 sql = 'select %s from table where condition1=1 and condition2=2' % ( ', '.join(fields)) 

我会build议坚持选项2(我总是使用它的查询比任何更复杂的SELECT * FROM table ),如果你想打印一个很好的方式,你可能总是使用一个单独的模块 。

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

[编辑在回应评论]
在一个方法中有一个SQLstring并不意味着你必须“列表”它:

 >>> class Foo: ... def fubar(self): ... sql = """\ ... select * ... from frobozz ... where zorkmids > 10 ... ;""" ... print sql ... >>> Foo().fubar() select * from frobozz where zorkmids > 10 ; >>> 

对于可以适合一两行的简短查询,我使用上面顶级投票解决scheme中的string文字解决scheme。 对于更长的查询,我将它们分解为.sql文件。 然后我使用包装函数来加载文件并执行脚本,如下所示:

 script_cache = {} def execute_script(cursor,script,*args,**kwargs): if not script in script_cache: with open(script,'r') as s: script_cache[script] = s return cursor.execute(script_cache[script],*args,**kwargs) 

当然,这通常存在于一个类中,所以我通常不需要明确地传递cursor 。 我也一般使用codecs.open() ,但这得到了一般的想法。 然后SQL脚本完全独立于自己的文件中,并带有自己的语法高亮显示。

除了@ user590028:

使用格式对我正在进行的工作很有帮助:

 statement = (ins "(name,standard_price,list_price,mes_type,uom_id,uom_po_id,type,procure_method,cost_method_categ_id,supply_method,sale_ok) " "VALUE ('{0}','{1}','{2}'".format(row[1],str(row[2]),str(row[2])) + ",'fixed',1,1,'product','make_to_stock','standard',1,'buy',True) RETURNING id" ) 

和:

 statement = ("INSERT INTO product_product " "(product_tmpl_id,default_code,active,valuation) " "VALUE " "('{0}','{1}',True,'manual_periodic')".format(str(row[0]), row[1]) ) 

我会build议一个非常简单的select。 只要在string前加一个r就可以像下面这样使用它:

 query=(r'SELECT f1,f2,f3 r'FROM table1 ' r'WHERE f4=cond1 ' r'AND f5=cond2 ') cursor.execute(str(query)) results=cursor.fetchall() cursor.close()