Skip to content
Snippets Groups Projects
Commit 7412d818 authored by Françoise Conil's avatar Françoise Conil
Browse files

Test d'options relationship(), lazy='dynamic'/'noload', collections en tant...

Test d'options relationship(), lazy='dynamic'/'noload', collections en tant que dictionnaire et non liste
parent 596f00c2
No related branches found
No related tags found
No related merge requests found
"""
https://docs.sqlalchemy.org/en/14/orm/basic_relationships.html
To establish a bidirectional relationship in one-to-many, where the “reverse” side is a
many to one, specify an additional relationship() and connect the two using the
relationship.back_populates parameter.
"""
from sqlalchemy import create_engine
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy.orm.session import Session
Base = declarative_base()
class Parent(Base):
__tablename__ = "parent"
id = Column(Integer, primary_key=True)
name = Column(String)
# A "noload" relationship never loads from the database, even when accessed.
# Below, the children collection is fully writeable, and changes to it will
# be persisted to the database as well as locally available for reading at
# the time they are added.
# https://docs.sqlalchemy.org/en/14/orm/collections.html#setting-noload-raiseload
# MAIS : Normal applications should not have to use "noload" for anything !!!
# https://github.com/sqlalchemy/sqlalchemy/discussions/7377
children = relationship("Child", lazy="dynamic")
def __repr__(self):
return f"<Parent (name={self.name}, children={self.children})>"
class Child(Base):
__tablename__ = "child"
id = Column(Integer, primary_key=True)
name = Column(String)
parent_id = Column(Integer, ForeignKey("parent.id"))
def __repr__(self):
return f"<Child (name={self.name})>"
if __name__ == "__main__":
engine = create_engine("sqlite:///one_to_many.2.dynamic.db", echo=False)
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
# cf ../basic-session.1.4.py
with Session(engine) as session:
jack = Parent(name="Jack")
alice = Child(name="Alice")
john = Child(name="John")
jack.children = [john, alice]
with session.begin():
session.add(jack)
session.add(john)
session.add(alice)
print(jack)
# <Parent (name=Jack, children=SELECT child.id AS child_id, child.name AS child_name, child.parent_id AS child_parent_id # noqa E501
# FROM child
# WHERE ? = child.parent_id)>
print(jack.children[:2])
# [<Child (name=John)>, <Child (name=Alice)>]
print(jack)
# <Parent (name=Jack, children=SELECT child.id AS child_id, child.name AS child_name, child.parent_id AS child_parent_id # noqa E501
# FROM child
# WHERE ? = child.parent_id)>
print(alice)
# <Child (name=Alice)>
"""
https://docs.sqlalchemy.org/en/14/orm/basic_relationships.html
To establish a bidirectional relationship in one-to-many, where the “reverse” side is a
many to one, specify an additional relationship() and connect the two using the
relationship.back_populates parameter.
"""
from sqlalchemy import create_engine
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy.orm.session import Session
Base = declarative_base()
class Parent(Base):
__tablename__ = "parent"
id = Column(Integer, primary_key=True)
name = Column(String)
# A "noload" relationship never loads from the database, even when accessed.
# Below, the children collection is fully writeable, and changes to it will
# be persisted to the database as well as locally available for reading at
# the time they are added.
# https://docs.sqlalchemy.org/en/14/orm/collections.html#setting-noload-raiseload
# MAIS : Normal applications should not have to use "noload" for anything !!!
# https://github.com/sqlalchemy/sqlalchemy/discussions/7377
children = relationship("Child", lazy="noload")
def __repr__(self):
return f"<Parent (name={self.name}, children={self.children})>"
class Child(Base):
__tablename__ = "child"
id = Column(Integer, primary_key=True)
name = Column(String)
parent_id = Column(Integer, ForeignKey("parent.id"))
def __repr__(self):
return f"<Child (name={self.name})>"
if __name__ == "__main__":
engine = create_engine("sqlite:///one_to_many.2.noload.db", echo=False)
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
# cf ../basic-session.1.4.py
with Session(engine) as session:
jack = Parent(name="Jack")
alice = Child(name="Alice")
john = Child(name="John")
jack.children = [john, alice]
with session.begin():
session.add(jack)
session.add(john)
session.add(alice)
print(jack)
# <Parent (name=Jack, children=[<Child (name=John)>, <Child (name=Alice)>])>
print(jack)
# <Parent (name=Jack, children=[])>
print(alice)
# <Child (name=Alice)>
"""
https://docs.sqlalchemy.org/en/14/orm/basic_relationships.html
https://docs.sqlalchemy.org/en/14/orm/collections.html#customizing-collection-access
ATTENTION aux changements de la clé du dictionnaire
https://docs.sqlalchemy.org/en/14/orm/collections.html#dealing-with-key-mutations-and-back-populating-for-dictionary-collections
"""
from sqlalchemy import create_engine
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.orm.session import Session
Base = declarative_base()
class Item(Base):
__tablename__ = "item"
id = Column(Integer, primary_key=True)
notes = relationship(
"Note",
collection_class=attribute_mapped_collection("keyword"),
backref="item",
cascade="all, delete-orphan",
)
def __repr__(self):
return f"<Item (name={self.id}, notes={self.notes})>"
class Note(Base):
__tablename__ = "note"
id = Column(Integer, primary_key=True)
keyword = Column(String)
text = Column(String)
item_id = Column(Integer, ForeignKey("item.id"))
def __repr__(self):
return f"<Node (keyword={self.keyword}, text={self.text})>"
if __name__ == "__main__":
engine = create_engine("sqlite:///one_to_many.dictionary.db", echo=False)
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
# cf ../basic-session.1.4.py
with Session(engine) as session:
item = Item()
n1 = Note(keyword="a", text="atext")
n1.item = item
n2 = Note(keyword="b", text="btext")
n2.item = item
with session.begin():
session.add(item)
session.add(n1)
session.add(n2)
print(item)
# <Item (name=1, notes={'a': <Node (keyword=a, text=atext)>, 'b': <Node (keyword=b, text=btext)>})> # noqa E501
print(n1)
# <Node (keyword=a, text=atext)>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment