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.

Reply via email to