2009-05-23 21 views
49

ठीक है तो मैं पाइथन में अनुभवी नहीं हूं।पायथन में SQL कथन में चर का उपयोग कैसे करें?

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

जहां var1 एक पूर्णांक है, var2 & var3 तार कर रहे हैं:

मैं निम्नलिखित पायथन कोड है।

मैं इन्हें क्वेरी पाठ के भाग के रूप सहित अजगर के बिना चर नाम लिख सकते हैं?

उत्तर

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

ध्यान दें कि पैरामीटर एक टुपल के रूप में पारित किए जाते हैं।

डेटाबेस एपीआई चर से बचने और उद्धरण के लिए उचित करता है। स्ट्रिंग स्वरूपण ऑपरेटर (%) का उपयोग नहीं सावधान रहें, क्योंकि

  1. यह किसी भी भागने या हवाले से नहीं करता है।
  2. यह अनियंत्रित स्ट्रिंग प्रारूप हमलों के लिए प्रवण है उदा। SQL injection
+0

दिलचस्प, यह क्यों वार्स के साथ अलग से की बजाय एक सरणी में काम करता है (var1, var2, var3)? – Andomar

+0

डीबी एपीआई चश्मा के अनुसार, ऐसा लगता है कि यह किसी भी तरह से हो सकता है: http://www.python.org/dev/peps/pep-0249/ –

+0

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

16

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

करते समय सावधान रहें तो आप बस अपने बयान करने के लिए चर का मान संलग्न: एक उपयोगकर्ता खुद ';DROP TABLE Users;' नामकरण कल्पना कीजिए - है यही कारण है कि आप से बचने एसक्यूएल, जो अजगर जब आप के लिए प्रदान करता उपयोग करने की आवश्यकता एक सभ्य तरीके से cursor.execute का उपयोग करें। यूआरएल में उदाहरण है:

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

असल में, यह एसक्यूएल से बच नहीं रहा है। यह परिवर्तनीय बाध्यकारी है, जो बहुत सरल और अधिक प्रत्यक्ष है। पार्सिंग के बाद मान SQL कथन में बंधे होते हैं, जिससे यह किसी भी इंजेक्शन हमले से प्रतिरक्षा बना देता है। –

+0

"लिटिल बॉबी टेबल्स, हम उसे बुलाते हैं।" अपने इनपुट को स्वच्छ करें। https://xkcd.com/327/ – mattmc3

40

अजगर डीबी एपीआई के विभिन्न कार्यान्वयन अलग प्लेसहोल्डर उपयोग करने के लिए है, तो आप पता लगाने के लिए जो एक प्रयोग कर रहे हैं की आवश्यकता होगी अनुमति दी जाती है - के साथ जैसे यह हो सकता है (MySQLdb):

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

या (जैसे अजगर मानक पुस्तकालय से sqlite3) के साथ:

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

या दूसरों अभी तक (VALUES के बाद आप (:1, :2, :3) हो सकता था, या "नाम शैलियों" (:fee, :fie, :fo) या (%(fee)s, %(fie)s, %(fo)s) जहां आप मानचित्र के बजाय execute पर दूसरे तर्क के रूप में एक नियम पारित करते हैं)। आपके द्वारा उपयोग किए जा रहे डीबी एपीआई मॉड्यूल में paramstyle स्ट्रिंग स्थिरता की जांच करें, और http://www.python.org/dev/peps/pep-0249/ पर पैरास्टाइल देखें, यह देखने के लिए कि सभी पैरामीटर-गुजरने वाली शैलियों क्या हैं!

+0

एक ही चीज़ करना संभव है लेकिन बाहरी SQL स्क्रिप्ट के साथ? – Novitoll

19

कई तरीकों से। नहीं, वास्तविक कोड में सबसे स्पष्ट एक (% साथ %s) का उपयोग करते हैं यह attacks के लिए खुला है।

यहाँ कॉपी-paste'd from pydoc of sqlite3:

# 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) 

अधिक उदाहरण अगर आप की जरूरत है:

# 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

कुछ डीबी-एपीआई कार्यान्वयन वास्तव में उनके चर के लिए% s का उपयोग करते हैं - सबसे विशेष रूप से PostgreSQL के लिए psycopg2। स्ट्रिंग प्रतिस्थापन के लिए% ऑपरेटर के साथ% s का उपयोग करने के साथ यह उलझन में नहीं है (हालांकि यह आसानी से है)। पोर्टेबिलिटी के लिए, अगर मैं डीबी-एपीआई के लिए एसक्यूएल पैरामीटर निर्दिष्ट करने का एक निश्चित मानक तरीका हो सकता हूं तो मैं वास्तव में अच्छा होगा। – ThatAintWorking

संबंधित मुद्दे