Hi Stanislav, Perhaps a way to avoid using `save` and `add_new` custom methods is to rely on listeners, perhaps `after_update` and `after_insert` will let you create historical records in some place else.
A couple of years ago I achieved this with SQLAlchemy Continuum (1), but I'm not sure in which state is that project now. You can also check these recipes (2) to see if any of those fit your specific needs. Bests, Martín 1- https://github.com/kvesteri/sqlalchemy-continuum 2- http://docs.sqlalchemy.org/en/latest/orm/examples.html?highlight=history#versioning-objects On Wed, Jan 31, 2018 at 2:27 PM Stanislav Lobanov <n10101...@gmail.com> wrote: > Hello, i need to create a system, that can store historical versions of > objects. > > Example model looks like: > > class User(Base): > id=Column(Integer) # ForeignKey > start=Column(DateTime) > end=Column(DateTime) > name=Column(String) > > I have implemented .add_new() and .save() methods on base class, which > performs custom logic on inserting rows into database. > > .add_new() method just assigns next id, default start and end date values > (start=datetime.now() and end=None). > > Rows where start has value and end is null are considered "live" rows, all > other rows are considered as "historical" > > .save() method changes current record dates (end date becomes current > moment, so this version is considered as "historical", because it has start > and end date lifetime moments set). Also, it performs some custom logic on > determining if new version of record should be created — it should not be > created, if name is not chaged. > > Example: > > user = User(name='User1') > user.add_new() > # user has values: id=1, start=<current datetime>, end=None, name='User1' > > user.name='test2' > user.save() > # user has values: id=1, start=<previous start>, end=<current datetime>, > name='test2' > > user.name='test2' > user.save() > # user has values: id=1, start=<previous start>, end=<current datetime>, > name='test2' and no insert performed, because name is not changed. > > > > This methods look for me inconsistent and error prone, so i want to be > able to use session.add() method. > > Are there any possibility to add support for custom process of saving and > modifying objects by using default sqlalchemy's apis? > > P.S.: in current example, table has composite pk (id, start, end), so id > is not auto incremented when inserting new row. Also, in such scenario we > can not have ForeignKey constraint. > > Thanks. > > -- > 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. > -- Martín +54 911 5112 9448 -- 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.