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 <[email protected]
> <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 [email protected] <javascript:>.
> > To post to this group, send email to [email protected]
> <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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.