On Tue, Jan 15, 2019 at 6:33 PM Daniel Leon <daniel19001...@gmail.com> wrote:
>
> from sqlalchemy import Column, ForeignKey, Integer, String, create_engine
> from sqlalchemy.ext.declarative import declarative_base
> from sqlalchemy.ext.declarative.base import _declarative_constructor
> from sqlalchemy.orm import Session, relationship, sessionmaker
> from sqlalchemy.orm.dynamic import AppenderQuery
>
>
> class BaseBase(object):
>
>     def __init__(self, **kwargs):
>         _declarative_constructor(self, **kwargs)
>         session.add(self)
>         session.commit()
>
>
> Base = declarative_base(cls=BaseBase, constructor=BaseBase.__init__)
>
>
> class Node(Base):
>
>     __tablename__ = 'node'
>
>     id = Column(Integer, primary_key=True)
>     label = Column(String)
>     parent_id = Column(Integer, ForeignKey('node.id'))
>     parent = relationship('Node', remote_side=id, back_populates='children')
>     children = relationship('Node', back_populates='parent')
>
>     def __repr__(self):
>         return self.label
>
>
> if __name__ == '__main__':
>     engine = create_engine('sqlite://', echo=True)
>     Base.metadata.create_all(engine)
>
>     Session = sessionmaker(bind=engine, expire_on_commit=False)
>     session = Session()
>
>     node = Node(label='root')
>     # Accessing children for first time so query is made
>     print node.children
>     child1 = Node(label='child1', parent_id=node.id)
>     # Accessing children again so no query is made and child1 is not there
>     print node.children
>     child2 = Node(label='child2', parent=node)
>     # Accessing children again so no query is made and child1 is not there, 
> but child2 is there
>     print node.children
>
> In my MCVE I have expire_on_commit=False. When I access node.children for the 
> first time, it makes that query. When I create child1 specifying parent_id, 
> it doesn't update node.children.

this is expected behavior

>
> I am converting a codebase from SQLObject, which queries every time you 
> access many-to-one field. With SQLAlchemy I know I can specify lazy='dynamic' 
> in children relationship, but that returns a query object so I'd have to do 
> node.children.all().

if you'd like foreign key updates to result in a flush, try out the
recipe at 
https://github.com/sqlalchemy/sqlalchemy/wiki/ExpireRelationshipOnFKChange
which should at this point cover every contingency.    but of course
long term you want to migrate off of that pattern as I don't know how
far the above recipe can be pushed.

>
> --
> 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