SQLAlchemy filtered relationship property

Viewed 35

I’m looking for a way to have a filtered property for a more general relationship — perhaps best explained in some code:

class Content(db.Model)
    id = db.Column(db.Integer(), primary_key=True
    title = db.Column(db.String(255))
    collection_id = db.Column(db.ForeignKey("collection.id"), nullable=False)
    type = db.Column(db.String(64), nullable=False, index=True)
    weight = db.Column(db.Integer())

class Collection(db.Model):
    id = db.Column(db.Integer(), primary_key=True)
    items = db.relationship(
        "Content",
        backref="collection",
        collection_class=sqlalchemy.ex.orderinglist.ordering_list("weight")
    )
    poems = "items filtered by type='poem'"

Collection.poems should in this case behave exactly the same as Collection.items except for being filtered. This means ideally write operations would propagate between those two:

collection = Collection(items=[
  Content(title="foo", type="other"),
  Content(title="bar", type="poem"),
])
assert [c.title for c in collection.items] == ["foo", "bar"]
assert [c.title for c in collection.poems] == ["bar"]
collection.poems.append(Content(title="baz", type="poem"))
assert [c.title for c in collection.items] == ["foo", "bar", "baz"]

I have tried:

  • Using a hybrid_property for this but of course appending new items didn’t work this way.
  • Using a separate db.relationship() but then the relationship collections don’t populate one another
0 Answers
Related