On Fri, May 4, 2018 at 9:49 PM, Dave von Umlaut <zedrd...@gmail.com> wrote: > I am trying to create a generic "versioned" SQLAlchemy table model, from > which I can derive further models. Among other things, I need a > is_latest_version column property that can be used to create appropriate > joins…
We have examples of this kind of versioning in the docs, and I just took a look and found they needed to be modernized, so I've done that and also added an additional example that includes both your "version_id" column as part of a composite primary key, as well as two different techniques to get the is_latest_version concept, one where it is persisted as a boolean value, and the other that shows your column_property version. We can't use @declared_attr for that right now as the declared_attr is invoked before we have access to the mapping or the mapped table. You can see this example at: http://docs.sqlalchemy.org/en/latest/_modules/examples/versioned_rows/versioned_rows_w_versionid.html the mapping for your column_property looks like: class Versioned(object): # we have a composite primary key consisting of "id" # and "version_id" id = Column(Integer, primary_key=True) version_id = Column(Integer, primary_key=True, default=1) @classmethod def __declare_last__(cls): alias = cls.__table__.alias() cls.calc_is_current_version = column_property( select([func.max(alias.c.version_id) == cls.version_id]).where( alias.c.id == cls.id ) ) > > Following code works fine: > > class Versioned(db.Model): > __abstract__ = True > id = Column(Integer, primary_key=True) > version = Column(Integer, primary_key=True) > > class Child(Versioned): > pass > > t = aliased(Child, name="t") > Child.is_latest_version = db.column_property( > select([ Child.version == db.func.max(t.version) ]) > .select_from(t) > .where(t.id == Child.id) > ) > > > > But I cannot figure any way to move the column property up to the parent > class. Any variation I attempt, bumps into class mapping issues… > > Closest I could think off, would be something like: > > class Versioned(db.Model): > __abstract__ = True > id = Column(Integer, primary_key=True) > version = Column(Integer, primary_key=True) > > @declared_attr > def is_latest_version(cls): > t = aliased(cls, name="t") > return db.column_property( > select([ cls.version == db.func.max(t.version) ]) > .select_from(t) > .where(t.id == cls.id) > ) > > class Child(Versioned): > pass > > > > But it throws an error: > `sqlalchemy.orm.exc.UnmappedClassError: Class 'app.models.Child' is not > mapped` > > Using quotes does not work either (query is executed with quoted fields as > literal strings). > > Is there any way to achieve this kind of column_property in a virtual class? > > Also… Not sure if that's related, but I also seem unable to implement > is_latest_version with a nicer join-based query (I suspect solving my Alias > issues might help): > … FROM child c1 JOIN child c2 ON c2.id = c1.id AND c2.version > c1.version > WHERE c2.id IS NULL > > > Thanks in advance for any help! > -- > Dave > > -- > 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. -- 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.