Saya mencoba menemukan cara terbaik untuk memformat string kueri sql. Ketika saya men-debug aplikasi saya, saya ingin masuk ke file semua string kueri sql, dan penting bahwa string tersebut diformat dengan benar.
Pilihan 1
def myquery():
sql = "select field1, field2, field3, field4 from table where condition1=1 and condition2=2"
con = mymodule.get_connection()
...
- Ini bagus untuk mencetak string sql.
- Ini bukan solusi yang baik jika stringnya panjang dan tidak sesuai dengan lebar standar 80 karakter.
pilihan 2
def query():
sql = """
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2"""
con = mymodule.get_connection()
...
Di sini kodenya jelas tetapi ketika Anda mencetak string kueri sql Anda mendapatkan semua ruang putih yang mengganggu ini.
u '\ npilih bidang1, bidang2, bidang3, bidang4 \ n_ _ ___ dari tabel \ n _ ___ di mana condition1 = 1 \ n _ ___ _and condition2 = 2'
Catatan: Saya telah mengganti spasi putih dengan garis bawah _
, karena mereka dipangkas oleh editor
Pilihan 3
def query():
sql = """select field1, field2, field3, field4
from table
where condition1=1
and condition2=2"""
con = mymodule.get_connection()
...
- Saya tidak suka opsi ini karena merusak kejelasan kode yang ditabulasikan dengan baik.
Pilihan 4
def query():
sql = "select field1, field2, field3, field4 " \
"from table " \
"where condition1=1 " \
"and condition2=2 "
con = mymodule.get_connection()
...
- Saya tidak suka opsi ini karena semua pengetikan tambahan di setiap baris dan sulit juga untuk mengedit kueri.
Bagi saya solusi terbaik adalah Opsi 2 tetapi saya tidak suka spasi ekstra ketika saya mencetak string sql.
Apakah Anda mengetahui opsi lain?
python
sql
string-formatting
ssoler
sumber
sumber
Jawaban:
Maaf telah memposting ke utas lama seperti itu - tetapi sebagai seseorang yang juga memiliki hasrat untuk pythonic 'terbaik', saya pikir saya akan membagikan solusi kami.
Solusinya adalah membangun pernyataan SQL menggunakan String Literal Concatenation python ( http://docs.python.org/ ), yang dapat dikualifikasikan di suatu tempat antara Opsi 2 dan Opsi 4
Contoh Kode:
sql = ("SELECT field1, field2, field3, field4 " "FROM table " "WHERE condition1=1 " "AND condition2=2;")
Berfungsi juga dengan f-string :
fields = "field1, field2, field3, field4" table = "table" conditions = "condition1=1 AND condition2=2" sql = (f"SELECT {fields} " f"FROM {table} " f"WHERE {conditions};")
Kelebihan:
sumber
"""
dan digunakantextwrap.dedent()
sebelum mengeluarkan"sql query"
untuk menghindari mengotak-atik string SQL (yang menggunakan tanda kutip tunggal sebagai standar)?Anda jelas telah mempertimbangkan banyak cara untuk menulis SQL sedemikian rupa sehingga tercetak dengan baik, tetapi bagaimana dengan mengubah pernyataan 'print' yang Anda gunakan untuk debug logging, daripada menulis SQL Anda dengan cara yang tidak Anda sukai? Dengan menggunakan opsi favorit Anda di atas, bagaimana dengan fungsi logging seperti ini:
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)
Ini juga akan membuatnya mudah untuk menambahkan logika tambahan untuk membagi string yang dicatat menjadi beberapa baris jika garis lebih panjang dari panjang yang Anda inginkan.
sumber
Cara terbersih yang saya temukan terinspirasi oleh panduan gaya sql .
sql = """ SELECT field1, field2, field3, field4 FROM table WHERE condition1 = 1 AND condition2 = 2; """
Pada dasarnya, kata kunci yang memulai klausa harus rata kanan dan nama bidang dll, harus rata kiri. Ini terlihat sangat rapi dan lebih mudah untuk di-debug juga.
sumber
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'
jika nilai kondisi harus berupa string, Anda dapat melakukan seperti ini:
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'"
sumber
format()
dengan string SQL, itu adalah bau kode utama.where condition1=:field1
dan kemudian meneruskan nilai sebagai parameter. Jika Anda menggunakan.format()
, akan ada cara untuk memasukkan a';DROP TABLE Users
ke SQL Anda. Lihat PEP-249 tentang cara menggunakan parameter dengan benar. python.org/dev/peps/pep-0249/#paramstyleAnda dapat menggunakan
inspect.cleandoc
untuk memformat pernyataan SQL yang dicetak dengan baik.Ini bekerja sangat baik dengan opsi 2 Anda .
Catatan:
print("-"*40)
ini hanya untuk mendemonstrasikan baris kosong superflous jika Anda tidak menggunakan 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()
Keluaran:
---------------------------------------- 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 ----------------------------------------
Dari dokumen :
sumber
Untuk menghindari pemformatan sepenuhnya , saya pikir solusi yang bagus adalah dengan menggunakan prosedur .
Memanggil prosedur memberi Anda hasil dari kueri apa pun yang ingin Anda masukkan ke dalam prosedur ini. Anda sebenarnya dapat memproses beberapa kueri dalam sebuah prosedur. Panggilan tersebut hanya akan mengembalikan kueri terakhir yang dipanggil.
MYSQL
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;
Python
sql =('call example;')
sumber
Anda dapat memasukkan nama bidang ke dalam "bidang" array, lalu:
sql = 'select %s from table where condition1=1 and condition2=2' % ( ', '.join(fields))
sumber
Saya akan menyarankan untuk tetap menggunakan opsi 2 (saya selalu menggunakannya untuk pertanyaan yang lebih kompleks dari
SELECT * FROM table
) dan jika Anda ingin mencetaknya dengan cara yang baik, Anda selalu dapat menggunakan modul terpisah .sumber
Untuk pertanyaan singkat yang dapat dimuat pada satu atau dua baris, saya menggunakan solusi literal string dalam solusi pilihan teratas di atas. Untuk pertanyaan yang lebih lama, saya memecahnya menjadi
.sql
file. Saya kemudian menggunakan fungsi pembungkus untuk memuat file dan menjalankan skrip, seperti: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)
Tentu saja ini sering terjadi di dalam kelas jadi saya biasanya tidak harus lulus
cursor
secara eksplisit. Saya juga biasanya menggunakancodecs.open()
, tetapi ini menyampaikan gambaran umum. Kemudian skrip SQL sepenuhnya mandiri dalam file mereka sendiri dengan penyorotan sintaksnya sendiri.sumber
sql = """\ select field1, field2, field3, field4 from table where condition1=1 and condition2=2 """
[edit in responese to comment]
Memiliki string SQL di dalam metode TIDAK berarti Anda harus "mentabulasi" -nya:
>>> class Foo: ... def fubar(self): ... sql = """\ ... select * ... from frobozz ... where zorkmids > 10 ... ;""" ... print sql ... >>> Foo().fubar() select * from frobozz where zorkmids > 10 ; >>>
sumber
select
. Jawaban saya tidak memiliki spasi. Apa yang membuat Anda beranggapan bahwa mereka sama?