पायथन में SQL कथन में चर का उपयोग कैसे करें?


91

ठीक है तो मैं पायथन में अनुभवी नहीं हूं।

मेरे पास निम्नलिखित पायथन कोड है:

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

var1पूर्णांक कहां है, var2और var3तार हैं।

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

जवाबों:


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

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

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

  1. यह कोई भागने या उद्धृत नहीं करता है।
  2. यह SQL इंजेक्शन जैसे अनियंत्रित स्ट्रिंग प्रारूप हमलों के लिए प्रवण है ।

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

DB API स्पेक्स के अनुसार, ऐसा लगता है कि यह किसी भी तरह से हो सकता है: python.org/dev/peps/pep-0249
Ayman Hourieh

9
@thekashyap फिर से ध्यान से पढ़ें। क्या असुरक्षित है स्ट्रिंग स्वरूपण ऑपरेटर का उपयोग कर रहा है %। वास्तव में, मैं जवाब में ऐसा कहता हूं।
अयमान हुइरीह

मेरा बुरा है .. मैं एक कल्पना की % बजाय ,स्ट्रिंग और चर beteween .. विभिन्न कारणों की वजह मेरा वोट-डाउन पूर्ववत नहीं कर सकते .. मैं व्यक्तिगत रूप से असुरक्षित जैसे शब्दों देखना चाहेंगे / हमला आदि विवरण में उल्लेख किया है जहाँ आप कहते हैं कि डॉन 't use %..
कश्यप

1
@ उत्तर कहता है कि स्ट्रिंग को प्रारूपित करने के लिए % ऑपरेटर का उपयोग न करें । %स्ट्रिंग में उन लोगों द्वारा cursor.executeसीधे इस्तेमाल किया जा रहा है , और क्योंकि यह जानता है कि यह एसक्यूएल पैदा कर रहा है यह आपकी रक्षा के लिए और अधिक कर सकता है।
मार्क रैनसम

66

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

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

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

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

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


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

46

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

यहाँ sqlite3 के pydoc से कॉपी-पेस्ट किया जाएगा :

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

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

23

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

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

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

13
वास्तव में, यह एसक्यूएल भागने नहीं है। यह परिवर्तनशील बंधन है, जो कहीं अधिक सरल और अधिक प्रत्यक्ष है। मान पार्स करने के बाद एसक्यूएल स्टेटमेंट में बंधे हैं, जिससे यह किसी भी इंजेक्शन हमले के लिए प्रतिरक्षा बन जाता है।
S.Lott

ठीक है, चाहे वह एसक्यूएल बच रहा हो या चर बंधन इस बात पर निर्भर करता है कि आपका डेटाबेस सर्वर / DB-API ड्राइवर कितना अच्छा या बुरा है। मैंने कुछ वास्तविक-दुनिया, व्यापक रूप से तैनात उत्पादन डेटाबेस देखे हैं जो अपने DB-API ड्राइवर को केवल तार पर डेटा और कोड आउट-ऑफ-बैंड रखने के बजाय, बचकर करते हैं। कहने की जरूरत नहीं है, मेरे पास उन तथाकथित "डेटाबेस" के लिए बहुत सम्मान नहीं है।
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.