Hello, 

I got stuck on a problem related to relatioships and cascades. In the docs 
<http://docs.sqlalchemy.org/en/latest/orm/cascades.html>, we have the 
following explanation:

Cascades:

 

*Mappers support the concept of configurable cascade behavior 
on relationship() 
<http://docs.sqlalchemy.org/en/latest/orm/relationship_api.html#sqlalchemy.orm.relationship>
 constructs. This 
refers to how operations performed on a “parent” object relative to a 
particular Session 
<http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session>
 should 
be propagated to items referred to by that relationship (e.g. “child” 
objects), and is affected by the relationship.cascade 
<http://docs.sqlalchemy.org/en/latest/orm/relationship_api.html#sqlalchemy.orm.relationship.params.cascade>
 option.*



It seems to me that the cascade attribute works only in the parent->child 
direction. Right now, I'm trying to figure out how to create one child with 
its parent_id, followed by an automatic refresh of its parent children list 
(i.e. without appending the child to the parent children list). Maybe it is 
not a good practice to use parent ids in ORM, but I'm wondering if it is 
possible to do it so. Sometimes we only want to create a child to a 
parent_id, without loading the parent object.


Let me show the source code that reproduce my problem:

from sqlalchemy import Table, Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, backref, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine

Base = declarative_base()

Base = declarative_base()

class Parent(Base):
    __tablename__ = 'parent'
    parent_id = Column(Integer, primary_key=True)
    children = relationship("Child", back_populates="parent", cascade="all")

class Child(Base):
    __tablename__ = 'child'
    child_id = Column(Integer, primary_key=True)
    name = Column(String)
    parent_id = Column(Integer, ForeignKey('parent.parent_id'))
    parent = relationship("Parent", back_populates="children", 
cascade="all")

engine = create_engine('sqlite:///:memory:', echo=False)
Session = sessionmaker(bind=engine)
Session.configure(bind=engine)
Base.metadata.create_all(engine)

s = Session()

p = Parent()
c1 = Child(name="C1")
p.children.append(c1)

s.add(p)
s.flush()

print([x.name for x in p.children])  # ['C1']

c2 = Child(parent_id=1, name="C2")
s.add(c2)
s.flush()

print([x.name for x in p.children])  # ['C1']

s.refresh(c2.parent) # This solves my problem, but I would like to know how 
to do it automatically without an explicit refresh

print([x.name for x in p.children])  # ['C1','C2']

s.close()



In this code, when I create child "C2" pointing it to parent_id=1, the 
parent object (children relationship) is not refreshed automatically. So, 
it only prints the first child: C1. After the refresh, I see both children 
C1 and C2.
Is there any option that refresh the parent authomatically? Is there 
anything that I'm missing?


Thanks!
Edans Sandes

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