2011-08-01 11 views
15

में तर्क के रूप में सूचियों या tuples उत्तीर्ण करना मेरे पास एक सूची है और django कच्चे sql के माध्यम से गुजरना चाहते हैं।django कच्चे sql

यहाँ मेरी सूची

region = ['US','CA','UK']

मैं यहाँ कच्चे एसक्यूएल का एक हिस्सा चिपकाने कर रहा हूँ।

results = MMCode.objects.raw('select assigner, assignee from mm_code where date between %s and %s and country_code in %s',[fromdate,todate,region])

अब यह नीचे त्रुटि देता है, जब मैं Django अजगर खोल में निष्पादित टपल भी पारित करके

Traceback (most recent call last): 
File "<console>", line 1, in <module> 
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 1412, in __iter__ 
query = iter(self.query) 
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 73, in __iter__ 
self._execute_query() 
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 87, in _execute_query 
self.cursor.execute(self.sql, self.params) 
File "/usr/local/lib/python2.6/dist-packages/django/db/backends/util.py", line 15, in execute 
return self.cursor.execute(sql, params) 
File "/usr/local/lib/python2.6/dist-packages/django/db/backends/mysql/base.py", line 86, in execute 
return self.cursor.execute(query, args) 
File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 166, in execute 
self.errorhandler(self, exc, value) 
File "/usr/lib/pymodules/python2.6/MySQLdb/connections.py", line 35, in defaulterrorhandler 
raise errorclass, errorvalue 
DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1") 

मैंने कोशिश की है, लेकिन कोई फायदा नहीं है। क्या कोई मेरी मदत कर सकता है।

धन्यवाद विक्रम

+0

क्या आप हमें एसक्यूएल क्वेरी स्ट्रिंग दे सकते हैं जो आपका ऐप निष्पादित करने का प्रयास कर रहा है? – niktrs

+0

यह मेरी एसक्यूएल क्वेरी है जो इसे सही तरीके से निष्पादित कर रही थी और यह परिणाम पुनर्प्राप्त कर रही है। 'असाइनर का चयन करें, mm_code से असाइन करें, जहां' 2011-07-21 'और' 2011-07-31 'और देशकोड (' यूएस ',' यूके ',' सीए ') में देशकोड है,' मैंने इतने सारे संयोजनों की कोशिश की है लेकिन हमेशा त्रुटि दे रहा है :-( – vkrams

+0

क्या आप सुनिश्चित हैं कि आपका ढांचा एक ही प्रश्न बनाता है? – niktrs

उत्तर

-1

खैर मैं कच्चे एसक्यूएल के खिलाफ नहीं हूँ, लेकिन आप उपयोग कर सकते हैं: MMCode.objects.filter(country_code__in=region, date__range=[fromdate,todate])

आशा है कि यह मदद करता है।

+0

खैर मेरी क्वेरी बहुत बड़ी है मैंने अभी यहां एक सबक्वायरी चिपकाई है। तो ओआरएम मेरे मामले में उपयोगी नहीं है और मैं ओआरएम में अच्छा नहीं हूं :-) – vkrams

+0

चूंकि आपका कच्चा वर्ग डीजेंगो खोल में काम करता है, इसलिए शायद आपको अपनी सूची के साथ करना होगा। रन टाइम पर गठित एसक्यूएल क्वेरी डीबग करने और खोजने का प्रयास करें। – Pannu

3

यह एक अच्छा समाधान नहीं है, क्योंकि आपको यह सुनिश्चित करना होगा कि आपका "क्षेत्र" मान SQL के लिए ठीक से बच निकला है। बहरहाल, यह केवल एक चीज मैं SQLite के साथ काम करने के लिए मिल सकता है:

sql = ('select assigner, assignee from mm_code ' 
    'where date between %%s and %%s and country_code in %s' % (tuple(region),)) 
results = MMCode.objects.raw(sql, [fromdate,todate]) 
6

एक टपल करने के लिए सूची कास्टिंग Postgres में काम करते हैं, हालांकि एक ही कोड DatabaseError: near "?": syntax error साथ sqlite3 के तहत विफल रहता है करता है तो यह इस लगता है बैकएंड-विशिष्ट होता है । कोड का लाइन बन गयी: खोल में तो

from django.db import models 

class MMCode(models.Model): 
    assigner = models.CharField(max_length=100) 
    assignee = models.CharField(max_length=100) 
    date = models.DateField() 
    country_code = models.CharField(max_length=2) 

:

results = MMCode.objects.raw('select assigner, assignee from mm_code where date between %s and %s and country_code in %s',[fromdate,todate,tuple(region)])

मैं बार/models.py में निम्नलिखित के साथ एक साफ Django 1.5.1 परियोजना पर इस परीक्षण किया

>>> from datetime import date 
>>> from bar.models import MMCode 
>>> 
>>> regions = ['US', 'CA', 'UK'] 
>>> fromdate = date.today() 
>>> todate = date.today() 
>>> 
>>> results = MMCode.objects.raw('select id, assigner, assignee from bar_mmcode where date between %s and %s and country_code in %s',[fromdate,todate,tuple(regions)]) 
>>> list(results) 
[] 

(ध्यान दें कि क्वेरी लाइन से थोड़ा यहाँ बदल गया है, डिफ़ॉल्ट तालिका Django द्वारा बनाए गए नाम का उपयोग करने के लिए, और टी में id कॉलम शामिल करने वह उत्पादन करता है ताकि ओआरएम शिकायत नहीं करे)

16

कम से कम PostgreSQL के लिए, एक सूची/tuple पैरामीटर SQL में एक सरणी में परिवर्तित किया गया है, उदा।

ARRAY['US', 'CA', 'UK'] 

जब यह किसी क्वेरी में डाला जाता है, यह अमान्य एसक्यूएल में परिणाम है -

SELECT assigner, assignee FROM mm_code 
WHERE date BETWEEN '2014-02-01' AND '2014-02-05' 
AND country_code IN ARRAY['US', 'CA', 'UK'] 

हालांकि, 'में' एसक्यूएल में खंड के तार्किक बराबर है -

SELECT assigner, assignee FROM mm_code 
WHERE date BETWEEN %s AND %s 
AND country_code = ANY(%s) 

... और जब यह क्वेरी पैरामीटर से भरी हुई है, परिणामी एसक्यूएल वैध है और काम करता है -

SELECT assigner, assignee FROM mm_code 
WHERE date BETWEEN '2014-02-01' AND '2014-02-05' 
AND country_code = ANY(ARRAY['US', 'CA', 'UK']) 

मुझे यकीन नहीं है कि यह अन्य डेटाबेस में काम करता है या नहीं, और यह बदलता है कि क्वेरी कैसे योजनाबद्ध है या नहीं।

1

मैं आज इस समस्या में भाग गया। Django बदल गया है (अब हमारे पास RawSQL() और दोस्तों हैं!), लेकिन सामान्य समाधान अभी भी वही है।

https://stackoverflow.com/a/283801/532513 के अनुसार सामान्य विचार है कि आपके region सरणी में तत्व होने के कारण प्लेसहोल्डर्स की समान संख्या को स्पष्ट रूप से जोड़ना है।

आपका कोड तो इस प्रकार दिखाई देगा:

sql = 'select assigner, assignee from mm_code where date between %s and %s and country_code in ({0})'\ 
     .format(','.join([%s] * len(region))) 
results = MMCode.objects.raw(sql, [fromdate,todate] + region) 

आपका एसक्यूएल स्ट्रिंग तो पहले ... between %s and %s and country_code in (%s, %s, %s) ... बन जाएगा और अपने परम प्रभावी रूप से [fromdate, todate, 'US', 'CA', 'UK'] होगा। इस तरह, आप डेटाबेस बैकएंड को सही ढंग से बचने और संभावित रूप से देश कोडों को एन्कोड करने की अनुमति देते हैं।

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