Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.8k views
in Technique[技术] by (71.8m points)

python - How to mark "lazy=raise_on_sql" collections on new SQLAlchemy model instance as loaded?

Say that I have two SQLAlchemy models that look like...

class Child(ModelBase):
    __tablename__ = "child"

    parent_id = sa.Column(sa.Integer, sa.ForeignKey("parent.id"))
    parent = orm.relationship(
        "Parent",
        backref=orm.backref("children", lazy="raise_on_sql"),
        lazy="joined",
    )


class Parent(ModelBase):
    __tablename__ = "parent"

    id = sa.Column(sa.Integer, primary_key=True)
    is_default = sa.Column(sa.Boolean)

... and I have a query to select parents and their children like...

parents = session.query(Parent) 
    .options(joinedload(Parent.children)) 
    .all()

If the query returns no parent records where is_default = True then I want to (1) create a new parent instance with is_default=True, and (2) add it to the parents list to be returned, like...

if not [p for p in parents if p.is_default]:
    parent = Parent(is_default=True)
    parents.add(parent)
    session.add(parent)
    session.flush() # necessary to get id of new record

return [{"parent": p, "children": p.children} for p in parents]

This works if a new record isn't created, but because parent wasn't loaded via the query, if a new record is created then the above raises...

sqlalchemy.exc.InvalidRequestError: 'Parent.children' is not available due to lazy='raise_on_sql'

I have a rough understanding of the session's identity map, and I know that I can issue another query with the new parent's id to select 0 rows and populate the map, but how can I mark the relationship as loaded for a new record without having to issue another query, especially one that is 100% useless as it's guaranteed that there aren't any children for the new parent?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...