2009-05-23 13 views
49

Pekala, Python'da bu kadar deneyimli değilim. var1 bir tam sayıdırPython'daki SQL deyimindeki değişkenler nasıl kullanılır?

cursor.execute("INSERT INTO table VALUES var1, var2, var3,") 

, var2 & var3 görürsün:

aşağıdaki Python kodu var.

Değişken adlarını, sorgu metninin bir parçası olarak dahil olmak üzere python olmadan nasıl yazabilirim?

cevap

57

Parametrelerin bir tuple olarak geçtiğini unutmayın.

Veritabanı API'si değişkenlerden kaçınıyor ve alıntı yapıyor.

  1. herhangi kaçan veya alıntı yapmaz, çünkü dize biçimlendirme operatörü (%) kullanmamaya özen gösterin.
  2. Kontrolsüz dize biçimindeki saldırılara örnektir. SQL injection. - Python sizin zaman sizin için sağladığı kaçan sql, kullanmak gerekir neden kendini ';DROP TABLE Users;' adlandırma bir kullanıcı düşünün: basitçe açıklamalara değişkenlerin değerler eklemek zaman
+0

İlginç, bu değişkenler ile ayrı ayrı yerine bir dizideki çalışır neden (Q1, var2, var3)? – Andomar

+0

DB API özelliklerine göre, her iki şekilde de olabilir: http://www.python.org/dev/peps/pep-0249/ –

+0

http://docs.python.org/2/library/ sqlite3.html # Kaçan – earthmeLon

16

http://www.amk.ca/python/writing/DB-API.html

dikkatli olun cursor.execute terimini iyi bir şekilde kullanın. url örnektir:

cursor.execute("insert into Attendees values (?, ?, ?)", (name, 
seminar, paid)) 
Python DB-API
+7

Aslında, SQL kaçan değil. Çok daha basit ve daha doğrudan olan değişken ciltleme. Değerler ayrıştırmadan sonra SQL ifadesine bağlanır ve herhangi bir enjeksiyon saldırısına karşı bağışıklık kazandırır. –

+0

"Küçük Bobby Tables, biz onu aradık." Girişlerinizi düzenleyin. https://xkcd.com/327/ – mattmc3

40

Farklı uygulamalar hangisini kullandığınız öğrenmek gerekir, böylece farklı tutucuları kullanmalarına izin verilir - olması gerektiği ile (örneğin MySQLdb):

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3)) 

ya da (örn Python standart kütüphaneden sqlite3) ile:

cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3)) 

veya başkalarını henüz (VALUES sonra, (:1, :2, :3) olabilir veya "adlandırılmış stiller" (:fee, :fie, :fo) veya (%(fee)s, %(fie)s, %(fo)s) Burada bir harita yerine execute ikinci bağımsız değişken olarak bir dict iletir). Kullandığınız DB API modülünde paramstyle dizgisi sabitini kontrol edin ve tüm parametre geçiş stillerinin ne olduğunu görmek için http://www.python.org/dev/peps/pep-0249/ parametresinde paramstyle'e bakın!

+0

Aynı şeyi harici SQL betiğiyle yapmak mümkün mü? – Novitoll

19

Birçok yol. DON'T gerçek kodda en belirgin olanı (%s%) kullanın, attacks'a açıktır.

Burada kopyalayıp paste'd from pydoc of sqlite3: Eğer gerekiyorsa

# Never do this -- insecure! 
symbol = 'RHAT' 
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) 

# Do this instead 
t = ('RHAT',) 
c.execute('SELECT * FROM stocks WHERE symbol=?', t) 
print c.fetchone() 

# Larger example that inserts many records at a time 
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00), 
      ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00), 
      ('2006-04-06', 'SELL', 'IBM', 500, 53.00), 
      ] 
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases) 

fazla örnek:

# Multiple values single statement/execution 
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', ('RHAT', 'MSO')) 
print c.fetchall() 
c.execute('SELECT * FROM stocks WHERE symbol IN (?, ?)', ('RHAT', 'MSO')) 
print c.fetchall() 
# This also works, though ones above are better as a habit as it's inline with syntax of executemany().. but your choice. 
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', 'RHAT', 'MSO') 
print c.fetchall() 
# Insert a single item 
c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', ('2006-03-28', 'BUY', 'IBM', 1000, 45.00)) 
+0

DB-API uygulamalarından bazıları, değişkenleri için% s kullanıyor - en önemlisi PostgreSQL için psycopg2. Dize değişimi için% işleci ile% s kullanılarak karıştırılmamalıdır (kolay olsa da). Eğer taşınabilirlik için DB-API için SQL parametrelerini tanımlamanın standart bir yolunu bulabilirsek gerçekten çok iyi olur. – ThatAintWorking

İlgili konular