बहुत पुरानी पोस्ट, लेकिन मैंने इस पर सिर्फ एक या दो घंटे बिताए, इसलिए मैं अपनी खोज को साझा करना चाहता था, खासकर जब से सूचीबद्ध कुछ अन्य टिप्पणियां काफी सही नहीं हैं।
टी एल; डॉ
बच्चे की मेज को एक विदेशी दें या मौजूदा जोड़ को संशोधित करें ondelete='CASCADE'
:
parent_id = db.Column(db.Integer, db.ForeignKey('parent.id', ondelete='CASCADE'))
और एक निम्नलिखित संबंधों का:
क) यह मूल तालिका पर है:
children = db.relationship('Child', backref='parent', passive_deletes=True)
बी) या बच्चे की मेज पर:
parent = db.relationship('Parent', backref=backref('children', passive_deletes=True))
विवरण
सबसे पहले, स्वीकार किए गए उत्तर के बावजूद, माता-पिता / बच्चे के संबंध का उपयोग करके स्थापित नहीं किया गया है relationship
, इसका उपयोग करके स्थापित किया गया है ForeignKey
। आप relationship
या तो माता-पिता या बच्चे की मेज पर रख सकते हैं और यह ठीक काम करेगा। हालांकि, स्पष्ट रूप से बच्चे की तालिकाओं पर, आपको backref
कीवर्ड तर्क के अतिरिक्त फ़ंक्शन का उपयोग करना होगा ।
विकल्प 1 (पसंदीदा)
दूसरा, SqlAlchemy कैस्केडिंग के दो अलग-अलग प्रकारों का समर्थन करता है। पहला, और जो मैं सुझाता हूं, वह आपके डेटाबेस में बनाया गया है और आमतौर पर विदेशी कुंजी घोषणा पर एक बाधा का रूप लेता है। PostgreSQL में यह इस तरह दिखता है:
CONSTRAINT child_parent_id_fkey FOREIGN KEY (parent_id)
REFERENCES parent_table(id) MATCH SIMPLE
ON DELETE CASCADE
इसका मतलब है कि जब आप किसी रिकॉर्ड को हटाते हैं parent_table
, तो child_table
डेटाबेस में आपके लिए सभी संबंधित पंक्तियों को हटा दिया जाएगा। यह तेज़ और विश्वसनीय है और शायद आपका सबसे अच्छा दांव है। आप इसे इस ForeignKey
तरह (चाइल्ड टेबल परिभाषा का हिस्सा) के माध्यम से SqlAlchemy में सेट करते हैं :
parent_id = db.Column(db.Integer, db.ForeignKey('parent.id', ondelete='CASCADE'))
parent = db.relationship('Parent', backref=backref('children', passive_deletes=True))
ondelete='CASCADE'
बात यह है कि बनाता है ON DELETE CASCADE
मेज पर।
पकड़ लिया!
यहाँ एक महत्वपूर्ण चेतावनी है। ध्यान दें कि मेरे पास कैसे relationship
निर्दिष्ट है passive_deletes=True
? यदि आपके पास ऐसा नहीं है, तो पूरी बात नहीं चलेगी। ऐसा इसलिए होता है क्योंकि जब आप मूल रिकॉर्ड हटाते हैं तो SqlAlchemy वास्तव में कुछ अजीब करता है। यह सभी चाइल्ड रो की विदेशी कुंजियों को सेट करता है NULL
। इसलिए यदि आप एक पंक्ति को parent_table
जहां id
= 5 से हटाते हैं , तो वह मूल रूप से निष्पादित होगी
UPDATE child_table SET parent_id = NULL WHERE parent_id = 5
आप यह क्यों चाहते हैं, मुझे कुछ पता नहीं है। मुझे आश्चर्य होगा कि कई डेटाबेस इंजनों ने भी आपको NULL
एक अनाथ बनाने के लिए एक वैध विदेशी कुंजी सेट करने की अनुमति दी । एक बुरे विचार की तरह लगता है, लेकिन शायद एक उपयोग मामला है। वैसे भी, यदि आप SqlAlchemy को ऐसा करने देते हैं, तो आप डेटाबेस को अपने द्वारा उपयोग किए जा रहे बच्चों को साफ करने में सक्षम होने से रोकेंगे ON DELETE CASCADE
। ऐसा इसलिए है क्योंकि यह उन विदेशी कुंजियों पर निर्भर करता है जो यह जानने के लिए कि कौन सी चाइल्ड रो को हटाना है। एक बार SqlAlchemy ने उन सभी को सेट कर दिया NULL
, डेटाबेस उन्हें हटा नहीं सकता। स्थापना passive_deletes=True
करने से रोकता है SQLAlchemy NULL
विदेशी कुंजी बाहर ing।
आप SqlAlchemy डॉक्स में निष्क्रिय डिलीट के बारे में अधिक पढ़ सकते हैं ।
विकल्प 2
दूसरा तरीका यह है कि आप SqlAlchemy को अपने लिए करने दें। यह के cascade
तर्क का उपयोग करके स्थापित किया गया है relationship
। यदि आपके पास मूल तालिका पर निर्धारित संबंध है, तो यह इस तरह दिखता है:
children = relationship('Child', cascade='all,delete', backref='parent')
यदि रिश्ता बच्चे पर है, तो आप इसे इस तरह करते हैं:
parent = relationship('Parent', backref=backref('children', cascade='all,delete'))
फिर, यह बच्चा है इसलिए आपको एक विधि को कॉल करना होगा backref
और कैस्केड डेटा को वहां डाल देना होगा।
इसके स्थान पर, जब आप मूल पंक्ति हटाते हैं, तो SqlAlchemy वास्तव में आपके लिए चाइल्ड रो को साफ करने के लिए डिलीट स्टेटमेंट चलाएगा। यह संभवत: इस डेटाबेस को संभालने के रूप में कुशल नहीं होगा यदि आप के लिए है तो मैं इसकी सिफारिश नहीं करता हूं।
यहाँ कास्केलेमी डॉक्स का समर्थन करता है जिन पर कैस्केडिंग सुविधाएँ हैं।