उद्धरण "मैं पायथन मल्टीप्रोसेसिंग, या os.fork () के साथ इंजन/कनेक्शन/सत्रों का उपयोग कैसे करूं?" अतिरिक्त जोर के साथ:
<ब्लॉकक्वॉट>SQLAlchemy Engine ऑब्जेक्ट मौजूदा डेटाबेस कनेक्शन के कनेक्शन पूल को संदर्भित करता है। इसलिए जब इस ऑब्जेक्ट को चाइल्ड प्रोसेस में दोहराया जाता है, तो लक्ष्य यह सुनिश्चित करना है कि कोई डेटाबेस कनेक्शन आगे नहीं बढ़े ।
और
<ब्लॉकक्वॉट>हालांकि, लेन-देन-सक्रिय सत्र या कनेक्शन साझा किए जाने के मामले में, इसके लिए कोई स्वचालित समाधान नहीं है; एक एप्लिकेशन को यह सुनिश्चित करने की आवश्यकता है कि एक नई चाइल्ड प्रक्रिया केवल नए कनेक्शन ऑब्जेक्ट और लेनदेन, साथ ही साथ ORM सत्र ऑब्जेक्ट शुरू करे।
यह समस्या लाइव ग्लोबल सत्र
. को इनहेरिट करने वाली फोर्कड चाइल्ड प्रोसेस से उत्पन्न होती है , जो एक कनेक्शन
. पर है . जब लक्ष्य
कॉल init
, यह इंजन
. के वैश्विक संदर्भों को अधिलेखित कर देता है और सत्र
, इस प्रकार बच्चे में उनकी पुनर्गणना 0 तक कम हो जाती है, जिससे उन्हें अंतिम रूप देने के लिए मजबूर होना पड़ता है। यदि आप उदाहरण के लिए बच्चे में विरासत में मिले सत्र के लिए एक तरह से या कोई अन्य संदर्भ बनाते हैं, तो आप इसे साफ होने से रोकते हैं - लेकिन ऐसा न करें। मुख्य
. के बाद शामिल हो गया है और हमेशा की तरह व्यवसाय में लौट आया है, यह अब संभावित रूप से अंतिम रूप देने का प्रयास कर रहा है - या अन्यथा सिंक से बाहर - कनेक्शन। यह क्यों कुछ पुनरावृत्तियों के बाद ही त्रुटि का कारण बनता है, मुझे यकीन नहीं है।
ग्लोबल्स का उपयोग करके इस स्थिति को संभालने का एकमात्र तरीका है जिस तरह से आप करते हैं
- सभी सत्र बंद करें
- कॉल करें
engine.dispose()
फोर्किंग से पहले। यह कनेक्शन को बच्चे को लीक होने से रोकेगा। उदाहरण के लिए:
def main():
global session
init()
try:
dummy = Dummy(value=1)
session.add(dummy)
session.commit()
dummy_id = dummy.id
# Return the Connection to the pool
session.close()
# Dispose of it!
engine.dispose()
# ...or call your cleanup() function, which does the same
p = multiprocessing.Process(target=target, args=(dummy_id,))
p.start()
p.join()
# Start a new session
session = Session()
dummy = session.query(Dummy).get(dummy_id)
assert dummy.value == 2
finally:
cleanup()
आपका दूसरा उदाहरण बच्चे में अंतिम रूप देने को ट्रिगर नहीं करता है, और इसलिए यह केवल काम करने लगता है, हालांकि यह पहले की तरह टूटा हुआ हो सकता है, क्योंकि यह अभी भी सत्र की एक प्रति प्राप्त कर रहा है और इसका कनेक्शन स्थानीय रूप से main<में परिभाषित किया गया है। /कोड> ।