2011-10-15 17 views
5

मेरे पास कुछ सिग्नल हैंडलर हैं जो Django उपयोगकर्ता पर काम करते हैं। इसके अतिरिक्त मैं दक्षिण का उपयोग कर रहा हूँ। ये सिग्नल हैंडलर कुछ माइग्रेशन पर निर्भर करते हैं जो पहले चलाना चाहिए।प्रोग्रामेटिक रूप से जांचें कि क्या सिंकडीबी चल रहा है

जब Django snycdb निष्पादित करता है और व्यवस्थापक उपयोगकर्ता बनाता है तो ये माइग्रेशन नहीं चलते हैं और सिग्नल हैंडलर अपवाद बढ़ाते हैं।

मैं यह पता लगाने का एक तरीका खोज रहा हूं कि Django वर्तमान में सिंकडब चलाता है ताकि सिग्नल हैंडल निष्पादन को छोड़ सके।

+1

दक्षिण में इसका मॉडल और एक टेबल है जहां यह जानकारी लॉग करता है जो माइग्रेशन चलाया गया है और जो नहीं था। हो सकता है कि आप इसका उपयोग यह जांचने के लिए कर सकें कि क्या माइग्रेशन की आवश्यकता है या नहीं? – Ski

+0

यह एक विकल्प भी होगा। लेकिन चूंकि हैंडलर अक्सर सहेजे गए मॉडल पर पोस्ट-सेव सिग्नल के लिए हैं, इसलिए मैं इस बिंदु पर डीबी को अतिरिक्त राउंडट्रिप से बचना चाहता हूं। –

+1

मुझे लगता है कि आप उस जानकारी को वैश्विक चर में सुरक्षित रूप से संग्रहीत कर सकते हैं और एप्लिकेशन शुरू होने पर इसे केवल एक बार पुनर्प्राप्त कर सकते हैं। – Ski

उत्तर

0

मुझे नहीं लगता कि ऐसा कोई तरीका syncdb चल रहा है पता करने के लिए है, लेकिन वहाँ एक रास्ता अजगर में अपवाद को संभालने के लिए है:

बस पकड़ने और अपवाद और pass:

try: 
    # code that deals with django user 
except ExceptionYouAreGetting: 
    # seems like syncdb is running, let's pass for now 
    pass 
+1

हालांकि यह एक विकल्प है, मैं हैंडलर में 'डेटाबेस एरर' निगलना नहीं चाहता क्योंकि यह अन्य गंभीर समस्याओं का भी संकेत दे सकता है। –

0

AFAIK यह पता लगाना संभव नहीं है कि सिंकडीबी चल रहा है या नहीं, हालांकि, जब सिंकडीबी या लोडडेटा चल रहा है, तो आपके सिग्नल को एक अतिरिक्त तर्क कच्चा होगा।

@receiver(post_save, sender=ModelA) 
def signal_handler(sender, **kwargs): 
    raw = kwargs.get('raw', False) 
    if not raw: 
     <do whatever> 

इस तरह, आप सिंकडब निष्पादित होने पर सिग्नल चलाने के लिए छोड़ सकते हैं।

+1

कच्चा तर्क केवल तभी सही है जब डेटा को एक स्थिरता से लोड किया जा रहा हो। हालांकि, कुछ चीजें (प्रारंभिक उपयोगकर्ता और डिफ़ॉल्ट साइट की तरह) जो django प्रारंभिक सिंकडीबी प्रक्रिया के दौरान बनाता है, को फिक्स्चर से लोड नहीं किया जाता है, इसलिए कच्चे भी किसी अन्य सहेजे गए परिदृश्य की तरह झूठा होगा। –

2

मैं डेटाबेस एरर अपवाद को फंसता हूं और जांचता हूं कि मैं जिस मॉडल का उपयोग करने की कोशिश कर रहा हूं, उसके लिए ContentType प्रविष्टि मौजूद है, अगर मुझे लगता है कि सिंकडीबी नहीं हो रहा है, अन्यथा लेनदेन को रोलबैक करें और मूल अपवाद को फिर से उठाएं। यह विधि केवल अतिरिक्त डीबी एक्सेस में होती है जब डेटाबेस एरर उठाया जाता है।

with transaction.commit_on_success(): 
     try: 
      content_type = ContentType.objects.get_for_model(kwargs['instance']) 
      for relation in WorkflowTypeRelation.objects.filter(content_type=content_type): 
       workflow_instance = WorkflowInstance.objects.create(content_object=kwargs['instance'], 
        workflow_type=relation.workflow_type) 
     except DatabaseError as database_error: 
      try: 
       ContentType.objects.get(model='workflowtyperelation') 
      except ContentType.DoesNotExist: 
       # Most probable running during syncdb phase, 
       # so ignore the exception 
       pass 
      except DatabaseError: 
       # ContentType model DB table doesn't exists, 
       # raise original exception 
       raise database_error 
      else: 
       # The ContentType model exists, 
       # there is something wrong with the DB 
       # raise original exception 
       transaction.rollback() 
       raise database_error 
संबंधित मुद्दे