2011-11-06 10 views
13

मैं एक मुद्दा है जहाँ मैं इसी प्रकार के एक एक त्रुटि प्राप्त हो रही है:SQLAlchemy StaleDataError ORM sqlalchemy.orm.exc.StaleDataError के माध्यम से डाला

"MyPyramidApplication Error"<class 'sqlalchemy.orm.exc.StaleDataError'>: DELETE statement on table 'page_view' expected to delete 6 row(s); Only 0 were matched. 

तो, मैं एक अच्छा विचार है क्या मुद्दा पैदा कर रहा है लेकिन मैं इसे हल करने में असमर्थ हूं।

मेरे पास एक पृष्ठदृश्य दृश्य है, जिसमें page_id और user_id पर एक विदेशी कुंजी है।

page_view_table = sa.Table(
    'page_view', 
    metadata, 
    sa.Column('id', sa.Integer, primary_key=True), 
    sa.Column('page_id', sa.Integer, sa.ForeignKey('guide.id')), 
    sa.Column('user_id', sa.Integer, sa.ForeignKey('user.id')), 
    sa.Column('last_view', sa.DateTime, nullable=False), 
    sa.UniqueConstraint('user_id', 'page_id'), 
    mysql_engine='InnoDB', 
    mysql_charset='utf8mb4' 
) 

यहाँ क्या संबंध, कुछ इसी तरह यह करने के लिए

orm.mapper(Page, page_table, 
    properties = { 
     'users_viewed': sa.orm.relation(
      User, 
      secondary=page_view_table, 
      backref='page'), 
    } 
) 

मैं एक डालने कथन का उपयोग मेरी डेटाबेस के लिए कुछ आइटम जोड़ने हूँ की तरह लग रही है::

यहाँ मॉडल लग रहा है की तरह है

ins = model.page_view_table.insert() 
sql = str(ins) 
sql += ' ON DUPLICATE KEY UPDATE last_view = :last_view' 
session = model.Session() 
session.execute(sql, page_views) 
mark_changed(session) 

जहां तक ​​मैं लॉग से बता सकता हूं, लेनदेन प्रतिबद्ध हो जाता है ठीक है और मैं डीबी में आइटम देखता हूं।

हालांकि, जब मैं ORM का उपयोग कर पृष्ठ आइटम को हटाने का प्रयास करता हूं, तो मुझे StaleDataError अपवाद मिलता है। लॉग को देखते हुए, मैं ओआरएम को डिलीट स्टेटमेंट जारी करता हूं लेकिन फिर त्रुटि के कारण वापस रोलिंग करता हूं।

मैंने डालने के बाद session.expire_all() के साथ-साथ session.expunge_all() के साथ प्रयोग करने का प्रयास किया है लेकिन वे बहुत उपयोगी नहीं थे और मुझे अभी भी त्रुटि है।

मैं एसक्यूएलकेमी लॉग में जो देखता हूं वह यहां है।

2011-11-05 18:06:08,031 INFO [sqlalchemy.engine.base.Engine][worker 3] DELETE FROM page_view WHERE page_view.page_id = %s AND page_view.user_id = %s 
2011-11-05 18:06:08,031 INFO [sqlalchemy.engine.base.Engine][worker 3] (13818L, 259L) 
2011-11-05 18:06:08,032 INFO [sqlalchemy.engine.base.Engine][worker 3] DELETE FROM page_view WHERE page_view.page_id = %s AND page_view.user_id = %s 
2011-11-05 18:06:08,033 INFO [sqlalchemy.engine.base.Engine][worker 3] (13818L, 259L) 
2011-11-05 18:06:08,033 INFO [sqlalchemy.engine.base.Engine][worker 3] ROLLBACK 

मैंने सोचा था कि डबल हटाने बयान एक पर संदेह किया जाता है, शायद गलत कॉन्फ़िगर ORM संबंध की ओर इशारा करते, लेकिन मैं यह बात है नहीं लगता।

उत्तर

3

मुझे लगता है कि मैं इस समस्या पर संकेत दे सकता हूं। संक्षिप्त संस्करण है: "आपको समस्या को हल करने के लिए मैन्युअल रूप से डेटाबेस में डेटा को संशोधित करना होगा"।

लंबा संस्करण: SQLite के साथ मेरा एक ही समस्या था। मेरे पास निम्न तालिका मैप की गई थी:

ingredients = Table('ingredients', metadata, 
    Column('recipe_title', Unicode, ForeignKey('recipes.title'), primary_key=True), 
    Column('product_title', Unicode, ForeignKey('products.title'), primary_key=True), 
    Column('amount', Integer, nullable=False), 
    Column('unit_title', Unicode, ForeignKey('units.title'))) 

समग्र प्राथमिक कुंजी देखें? मैं किसी भी तरह से एक ही नुस्खा_शीर्षक/product_title जोड़ी के साथ दो पंक्तियों को सम्मिलित करने में कामयाब रहे। मुझे यह पता लगाने के लिए surprized था कि इस तालिका के लिए SQLite के पक्ष में एक भी बाधा नहीं थी (कोई प्राथमिक कुंजी नहीं, कोई फ्रेगिन कुंजी नहीं - यह सिर्फ एक सादा वेनिला टेबल था), लेकिन अच्छी तरह से - जिस तरह से sqlalchemy चला जाता है, मेरे नहीं व्यापार।

तब जब मैंने उन दो पंक्तियों से युक्त एक स्थायी वस्तु को हटाने की कोशिश की, तो स्क्लेल्चेमी ने देखा कि इसकी बाधाओं का उल्लंघन किया गया था और उसने 'StaleDataError' फेंक दिया। आखिरकार मुझे SQLite तालिका से मैन्युअल रूप से एक डुप्लिकेटिन्ग पंक्ति को हटाना पड़ा।

1

हालांकि कॉलम को primary_key के रूप में चिह्नित किया जा सकता है, यह सुनिश्चित करें कि यह डेटाबेस स्तर पर भी लागू है (उदाहरण के लिए जब डेटाबेस किसी भिन्न उपकरण द्वारा बनाया गया था)। MySQL में इसका मतलब है कि वे PRIMARY KEY हैं और न केवल KEY हैं।

मेरे मामले में primary_key (समग्र) के रूप में चिह्नित 2 कॉलम थे, लेकिन एक ही (माना जाता है) अद्वितीय id के साथ कई पंक्तियां थीं।

+0

इस उत्तर को बेहतर बनाने के लिए कृपया पृष्ठ --- जैसे कि "हालांकि कॉलम को प्राथमिक_की के रूप में चिह्नित किया जा सकता है, डेटाबेस उन्हें इस तरह लागू नहीं कर सकता है। सुनिश्चित करें कि वे प्राथमिक कुंजी हैं और कुंजी नहीं कर रहे <<आवश्यक चरणों को सम्मिलित करें>" या यदि यह मूल प्रश्न का उत्तर नहीं है कृपया इसे हटाएं। –