On Thursday, September 27, 2012 9:21:57 AM UTC-4, Shawn Wheatley wrote: > > > >> the most idiomatic way to handle this is to merge the objects in: >> >> obj = session.merge(existing_object) >> >> this will emit a SELECT for the existing row, then copy the state of >> "existing_object" to an object located for that primary key, if found. >> It ensures that the correct choice of "pending" or "persistent" is made >> depending on if the row already exists. >> > > Thanks for your response Michael. It wasn't clear from my original post, > but I am using merge to copy from PROD to DEV. My merge function looks > something like this (simplified, but I'm copying multiple entities) > > session_dest.merge(entity) > session_dest.commit() > session_dest.expunge_all() # large object graphs were causing me to run > low on memory, so I merge them one at a time and then clear the local cache. > > So, assuming DEV has a single record {acct_id: 1, env_id: 1} and I'm > copying a record {acct_id: 1, env_id: 4} from PROD, it incorrectly thinks > that this record should be INSERTed, when in fact there is a constraint > (acct_id must be unique) that prevents this. > > The more I evaluate this, the more I think that correctly modeling the > unique constraint will fix my problem. Then my before_update handler would > function but would properly UPDATE the record. >
I updated my class to include a UniqueConstraint on acct_id: class CiAcctK(DeclarativeBase): __tablename__ = 'ci_acct_k' __table_args__ = {} #column definitions acct_id = Column(u'acct_id', CHAR(length=10), ForeignKey('ci_acct.acct_id'), primary_key=True, nullable=False) env_id = Column(u'env_id', NUMERIC(precision=6, scale=0), primary_key=True, nullable=False) uix_1 = UniqueConstraint(u'acct_id') I also separated out my event handlers: @event.listens_for(CiAcctK, "before_update") def CiAcctK_gen_default_upd(mapper, connection, instance): print "got here! update" instance.env_id = ENV_ID @event.listens_for(CiAcctK, "before_insert") def CiAcctK_gen_default_ins(mapper, connection, instance): print "got here! insert" instance.env_id = ENV_ID Sure enough, when executing the session.merge, SA is trying to INSERT the record {acct_id: 1, env_id: 4} even though acct_id: 1 already exists. Any thoughts on what I'm doing wrong? Shawn -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To view this discussion on the web visit https://groups.google.com/d/msg/sqlalchemy/-/w4VUwG5bh48J. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.