私はSQLクエリ文字列をフォーマットするための最良の方法を見つけようとしています。アプリケーションをデバッグするとき、すべてのsqlクエリ文字列をファイルに記録したいので、文字列が適切にフォーマットされていることが重要です。
オプション1
def myquery():
sql = "select field1, field2, field3, field4 from table where condition1=1 and condition2=2"
con = mymodule.get_connection()
...
オプション2
def query():
sql = """
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2"""
con = mymodule.get_connection()
...
ここではコードは明確ですが、SQLクエリ文字列を印刷すると、これらの迷惑な空白がすべて表示されます。
u '\ nselect field1、field2、field3、field4\n _____fromテーブル\ n____where condition1 = 1\n____ _ and condition2 = 2 '
注:空白はアンダースコア_
に置き換えました。これらはエディターによってトリミングされるためです
オプション
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()
...
私にとって最良の解決策はオプション2ですが、SQL文字列を印刷するときに余分な空白が好きではありません。
他のオプションを知っていますか?
このような古いスレッドに投稿してすみませんが、Pythonicの「ベスト」への情熱も共有している人として、私はソリューションを共有すると思いました。
解決策は、Pythonの文字列リテラル連結( http://docs.python.org/ )を使用してSQLステートメントを構築することです。これは、オプション2とオプション4の間のどこかに修飾できます。
コードサンプル:
sql = ('select field1, field2, field3, field4 '
'from table '
'where condition1=1 '
'and condition2=2 ')
SQLを記述して大丈夫なようにSQLを記述する多くの方法を明らかに検討しましたが、SQLを好きではない方法で記述するのではなく、デバッグロギングに使用する 'print'ステートメントを変更してはどうでしょうか。上記のお気に入りのオプションを使用して、次のようなロギング機能はどうですか:
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)
これにより、行が目的の長さより長い場合、ログに記録された文字列を複数の行に分割するためのロジックを追加することも簡単になります。
私が出会った最もクリーンな方法は、 SQLスタイルガイド に触発されています。
sql = """
SELECT field1, field2, field3, field4
FROM table
WHERE condition1 = 1
AND condition2 = 2;
"""
基本的に、句を開始するキーワードは右揃えにし、フィールド名などは左揃えにする必要があります。これは非常にきれいに見え、デバッグも簡単です。
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'
条件の値を文字列にする必要がある場合、次のようにできます。
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'"
完全にフォーマットするを回避するには、 procedures を使用するのがよい解決策だと思います。
プロシージャを呼び出すと、このプロシージャに入れる必要なクエリの結果が得られます。実際には、プロシージャ内で複数クエリの処理を実行できます。呼び出しは、最後のクエリが呼び出されただけを返します。
DROP PROCEDURE IF EXISTS example;
DELIMITER //
CREATE PROCEDURE example()
BEGIN
SELECT 2+222+2222+222+222+2222+2222 AS this_is_a_really_long_string_test;
END //
DELIMITER;
#calling the procedure gives you the result of whatever query you want to put in this procedure. You can actually process multiple queries within a procedure. The call just returns the last query result
call example;
sql =('call example;')
sql = """\
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2
"""
>>> class Foo:
... def fubar(self):
... sql = """\
... select *
... from frobozz
... where zorkmids > 10
... ;"""
... print sql
...
>>> Foo().fubar()
select *
from frobozz
where zorkmids > 10
;
>>>
非常に簡単なオプションをお勧めします。文字列の前に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()
@ user590028に加えて:
Formatの使用は、私が取り組んでいたものに役立ちました。
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])
)
オプション2に固執することをお勧めします(私は常に、SELECT * FROM table
)そして、それを素敵な方法で印刷したい場合は、常に separate module を使用できます。
1行または2行に収まる短いクエリの場合、上記の上位投票ソリューションで文字列リテラルソリューションを使用します。より長いクエリの場合は、_.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スクリプトは独自のファイルに完全に含まれ、独自の構文が強調表示されます。
フィールド名を配列「フィールド」に入れてから、
sql = 'select %s from table where condition1=1 and condition2=2' % (
', '.join(fields))