New to pdb. Does this look correct? class DebugSession(Session):
def _flush(self, objects=None): pdb.set_trace() super()._flush(objects) factory = sqlalchemy.orm.sessionmaker(bind=engine, class_=DebugSession) Program terminates when trying to call _flush(). api_1 | > /app/common/sqlalchemy.py(17)_flush() api_1 | -> super()._flush(objects) On Monday, May 7, 2018 at 7:27:03 PM UTC-7, Mike Bayer wrote: > > can you perhaps place a "pdb.set_trace()" inside of session._flush()? > using the debugger you can see the source of every flush() call. > Generally, it occurs each time a query is about to emit SQL. > > On Mon, May 7, 2018 at 9:37 PM, Colton Allen <cmana...@gmail.com > <javascript:>> wrote: > > What exactly causes the session to flush? I'm trying to track down a > nasty > > bug in my versioning system. > > > > Sorry for the long code dump. I retooled > > examples/versioned_history/history_meta.py so it should look familiar. > The > > function that's breaking is "column_has_changed". I've added some logs > as > > well. > > > > # WHEN IT WORKS! > > > > CRITICAL:root:BEFORE MAPPING NEW VALUES > > CRITICAL:root:BEFORE SAVE > > CRITICAL:root:BEFORE REVISE > > CRITICAL:root:CHECK COLUMN CHANGES > > CRITICAL:root:AFTER REVISE > > CRITICAL:root:flush! > > CRITICAL:root:AFTER SAVE > > CRITICAL:root:flush! > > > > # WHEN IT DOESN'T WORK! > > > > CRITICAL:root:BEFORE MAPPING NEW VALUES > > CRITICAL:root:BEFORE SAVE > > CRITICAL:root:BEFORE REVISE > > CRITICAL:root:flush! > > CRITICAL:root:CHECK COLUMN CHANGES > > CRITICAL:root:AFTER REVISE > > CRITICAL:root:AFTER SAVE > > CRITICAL:root:flush! > > > > controller.py > > > > for k, v in dict.items(): > > setattr(model, k, v) > > model.revise() > > db.session.add(model) > > db.session.commit() > > > > model.py > > > > class RevisionMixin: > > """Version control manager.""" > > > > def revise(self): > > db.session.add(self) > > write_revision(self) > > > > version.py > > > > def write_revision(target): > > target_mapper = orm.object_mapper(target) > > revision_class = target.__versioned__['model'] > > revision_mapper = revision_class.__mapper__ > > > > object_changed = False > > state = {} > > > > for column in iter_mapper_columns(target_mapper, revision_mapper): > > state[column.key] = getattr(target, column.key) > > column_changed = column_has_changed(target, column.key) > > object_changed = object_changed or column_changed > > > > for relationship, changed in iter_relationships(target, > target_mapper): > > if hasattr(revision_class, relationship.key): > > state[relationship.key] = getattr(target, relationship.key) > > object_changed = object_changed or changed > > > > if not isinstance(target.id, str) or object_changed: > > _write_revision(target, state) > > > > > > def _write_revision(target, state): > > version = target.version or 0 > > version = version + 1 > > state['version'] = version > > state['updated_at'] = db.now() > > state['primary'] = target > > > > revision = target.__versioned__['model'](**state) > > db.session.add(revision) > > > > target.version = version > > target.updated_at = state['updated_at'] > > > > > > def iter_mapper_columns(primary, revision): > > mappers = zip(primary.iterate_to_root(), revision.iterate_to_root()) > > for om, hm in mappers: > > if hm.single: > > continue > > for column in iter_shared_columns(om, hm): > > yield column > > > > > > def iter_shared_columns(mapper, comparison_mapper): > > for comparison_mapper_column in comparison_mapper.local_table.c: > > if 'version_meta' in comparison_mapper_column.info: > > continue > > > > try: > > mapper_column = > > mapper.local_table.c[comparison_mapper_column.key] > > yield mapper.get_property_by_column(mapper_column) > > except UnmappedColumnError: > > continue > > > > > > def iter_relationships(target, mapper): > > for prop in mapper.iterate_properties: > > if isinstance(prop, RelationshipProperty): > > passive = attributes.PASSIVE_NO_INITIALIZE > > changed = attributes.get_history( > > target, prop.key, passive=passive).has_changes() > > yield prop, changed > > > > > > def column_has_changed(target, column_name): > > # Sometimes the instance state history can't be properly > > # calculated? No flushing during versioning. Unsure why its not > > # working. > > added, _, deleted = attributes.get_history(target, column_name) > > return bool(added or deleted) > > > > > > def relationship_has_changed(prop): > > for p in prop.local_columns: > > if p.foreign_keys: > > return True > > return False > > > > > > -- > > SQLAlchemy - > > The Python SQL Toolkit and Object Relational Mapper > > > > http://www.sqlalchemy.org/ > > > > To post example code, please provide an MCVE: Minimal, Complete, and > > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > > description. > > --- > > You received this message because you are subscribed to the Google > Groups > > "sqlalchemy" group. > > To unsubscribe from this group and stop receiving emails from it, send > an > > email to sqlalchemy+...@googlegroups.com <javascript:>. > > To post to this group, send email to sqlal...@googlegroups.com > <javascript:>. > > Visit this group at https://groups.google.com/group/sqlalchemy. > > For more options, visit https://groups.google.com/d/optout. > -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.