2012-03-29 9 views
5

मैं Django के साथ डीबी पर bitwise सवाल कैसे कर सकता हूँ?
मुझे दस्तावेज़ों में इसके बारे में कुछ भी नहीं मिला है।
क्या मुझे एक क्वेरीसेट पुनर्प्राप्त करना चाहिए और फिर प्रोग्रामिक रूप से फ़िल्टर करना चाहिए?डीजेगो में डीबी बिटवाईड क्वेरी कैसे करें?

यदि आप रुचि रखते हैं, तो मैं प्रदर्शन को बेहतर बनाने के लिए IN() कथनों के विकल्प के रूप में बिटवाई ऑप्स का उपयोग करता हूं।
मेरे पास एक डीबी है जिसमें लाखों आइटम (रिकॉर्ड) हैं। कुछ फ़ील्ड किसी आइटम प्रॉपर्टी के बाइनरी प्रस्तुति का उपयोग करते हैं।
उदाहरण के लिए: रंग क्षेत्र से अधिक मान प्रदान कर सकते हैं, तो यह इतना तरह संरचित है:

0001 - Red 
0010 - Green 
0100 - Blue 
1000 - White 

(इन बाइनरी मान हैं)
तो अगर एक आइटम लाल और नीले रंग, रंग है फ़ील्ड में 0101 होगा।
जब कोई उपयोगकर्ता डीबी से पूछताछ करता है, तो मैं थोड़ा सा उपयोग करता हूं- या मिलान खोजने के लिए (IN() जो बहुत धीमा है)।

उत्तर

4

चेक django-bitfield, यह काम करता है अच्छी तरह से w/PostgreSQL (शायद यह भी अच्छी तरह से MySQL)

+0

हाय, मैं वास्तव में MySQL (MongoDB की ओर पलायन के बारे में सोच है, लेकिन यह बिटवाइज़ प्रश्नों एटीएम का समर्थन नहीं करता) का उपयोग कर रहा – user1102018

+0

@ user1102018 मैं सिर्फ कोड देख लिया है, यह MySQL पर काम करना चाहिए, क्योंकि यह सामान्य पूर्णांक फ़ील्ड और सामान्य bitwise और | | का उपयोग करता है जो सभी MySQL द्वारा समर्थित हैं। – okm

3

आप F objects साथ डेटाबेस स्तरीय बिटवाइज़ कार्रवाई कर सकते हैं।

यदि फ़ील्ड गैर-ऋणात्मक है, तो इसका मतलब है कि field & mask > 0 को (field > 0) AND (field >= (field & mask)) के रूप में फिर से लिखा जा सकता है। यदि आप यह जांचना चाहते हैं कि mask के सभी बिट्स लागू होते हैं ((field & mask) == mask), तो आप प्रत्येक बिट के लिए पिछली अभिव्यक्ति बना सकते हैं और फिर एसक्यूएल AND के माध्यम से शर्तों को मर्ज कर सकते हैं। कृपया उदाहरण देखें कि यह कैसे किया जा सकता है। (कस्टम क्वेरीसमूह सिर्फ सुविधा के लिए है। आप पुराने Django संस्करण का उपयोग करते हैं आप has_one_of और has_all अलग कार्य या classmethods के रूप में, या बेहतर PathThroughManager लागू कर सकते हैं)। नोट 1 * F बिटवाइज़ कार्यवाही पूर्ण कोष्टक मजबूर करने के लिए एक समाधान है, अन्यथा (संस्करण 1.5 के लिए के रूप में) django बुरा एसक्यूएल का उत्पादन करेगा (colors >= colors & mask, तुलना उच्च प्राथमिकता है, इसलिए यह TRUE & mask मतलब होगा)

import operator 
from django.db import models 
from django.db.models import Q, F 

_bit = lambda x: 2**(x-1) 
RED = _bit(1) 
GREEN = _bit(2) 
BLUE = _bit(3) 
WHITE = _bit(4) 


class ItemColorsQuerySet(models.QuerySet): 

    def has_one_of(self, colors): 
     """ 
      Only those that has at least one of provided colors 
     """ 
     return self.filter(
      colors__gt=0, 
      # field value contains one of supplied color bits 
      colors__gte=1 * F('colors').bitand(reduce(operator.or_, colors, 0)) 
     ) 

    def has_all(self, colors): 
     """ 
      Has all provided colors (and probably others) 
     """ 
     # filter conditions for all supplied colors: 
     # each one is "field value has bit that represents color" 
     colors_q = map(lambda c: Q(colors__gte=1 * F('colors').bitand(c)), colors) 
     # one complex Q object merged via sql AND: 
     # colors>0 and all color-bit conditions 
     filter_q = reduce(operator.and_, colors_q, Q(colors__gt=0)) 
     return self.filter(filter_q) 


class Item(models.Model): 

    name = models.CharField(max_length=100, unique=True) 
    # can handle many colors using bitwise logic. Zero means no color is set. 
    colors = models.PositiveIntegerField(default=0) 

    objects = ItemColorsQuerySet.as_manager() 
+0

स्रोत जहां से आपने इसे सीखा। या यह आपका खुद का विचार है? –

+0

हां, यह मेरा स्वयं का विचार था, समाधान के दौरान मुझे यह प्रश्न मिला, और जब मैंने अंततः इसे हमारे प्रोजेक्ट में कार्यान्वित किया, तो विचार को साझा करने के लिए वापस आया। –

6

postgres के लिए DB आप हो सकता है django orm के साथ .extra() पैराम का उपयोग करें।

उदाहरण के लिए:

SomeModel.objects.extra(where=['brand_label & 3 = 3']) 
संबंधित मुद्दे