2013-03-26 5 views
5

मुद्दा यह है कि जब मैं किसी ऑब्जेक्ट को किसी नए राज्य में जाता हूं तो मुझे सूचित करने के लिए SQLAlchemy का उपयोग कैसे करें Iडीबी अपडेट के बाद मुझे एसक्यूएलकेमी ओआरएम ऑब्जेक्ट की पिछली स्थिति कैसे मिल सकती है?

मैं SQLAlchemy ORM (घोषणात्मक) का उपयोग कर रहा एक वस्तु अद्यतन करने के लिए:

class Customer(declarative_base()): 

    __table_name__ = "customer" 

    id = Column(Integer, primary_key=True) 
    status = Column(String) 

मुझे पता है कि जब एक वस्तु एक राज्य में प्रवेश करती चाहते हैं। विशेष रूप से एक अद्यतन के बाद जारी किया गया है और जब राज्य बदलता है। जैसे Customer.status == 'registered' और इससे पहले एक अलग राज्य था।

मैं वर्तमान में एक 'set' विशेषता घटना के साथ इस कर रहा हूँ:

from sqlalchemy import event 
from model import Customer 

def on_set_attribute(target, value, oldvalue, initiator): 
    print target.status 
    print value 
    print oldvalue 

event.listen(
     Customer.status, 
     'set', 
     on_set_attribute, 
     propagate=True, 
     active_history=True) 

मेरे कोड 'set' हर बार है कि विशेषता पर कहा जाता है आग, और मैं जाँच अगर value और oldvalue अलग हैं। समस्या यह है कि target पैरामीटर पूरी तरह से गठित नहीं है, इसलिए इसमें अभी तक सभी विशेषता मान पॉप्युलेट नहीं हैं।

क्या ऐसा करने का कोई बेहतर तरीका है? धन्यवाद!

उत्तर

10

मेरा समाधान 'set_ AttushEvent' के बजाय 'after_flush' सत्र Event का उपयोग करना था।

agronholm पर बहुत धन्यवाद जिन्होंने उदाहरण सत्र सत्र कोड प्रदान किया जो विशेष रूप से किसी ऑब्जेक्ट के मूल्य और पुरानेव्यू की जांच करता है।

def get_old_value(attribute_state): 
    history = attribute_state.history 
    return history.deleted[0] if history.deleted else None 


def trigger_attribute_change_events(object_): 
    for mapper_property in object_mapper(object_).iterate_properties: 
     if isinstance(mapper_property, ColumnProperty): 
      key = mapper_property.key 
      attribute_state = inspect(object_).attrs.get(key) 
      history = attribute_state.history 

      if history.has_changes(): 
       value = attribute_state.value 
       # old_value is None for new objects and old value for dirty objects 
       old_value = get_old_value(attribute_state) 
       handler = registry.get(mapper_property) 
       if handler: 
        handler(object_, value, old_value) 


def on_after_flush(session, flush_context): 
    changed_objects = session.new.union(session.dirty) 
    for o in changed_objects: 
     trigger_attribute_change_events(o) 

event.listen(session, "after_flush", on_after_flush) 

registry एक शब्दकोश जिसका चाबियाँ हैं MapperProperty की और जिनके मान ईवेंट हैंडलर्स हैं:

नीचे समाधान अपने कोड का एक संशोधन है। session, event, inspect, और object_mapper सभी sqlalchemy कक्षाएं और कार्य हैं।

2

before_update ईवेंट या before_flush ईवेंट का उपयोग समय के बाद में होने वाली घटना को रोकने के लिए करें।

संबंधित मुद्दे

 संबंधित मुद्दे