examples.large_collection.large_collection
优质
小牛编辑
134浏览
2023-12-01
from sqlalchemy import Column from sqlalchemy import create_engine from sqlalchemy import ForeignKey from sqlalchemy import Integer from sqlalchemy import MetaData from sqlalchemy import String from sqlalchemy import Table from sqlalchemy.orm import mapper from sqlalchemy.orm import relationship from sqlalchemy.orm import sessionmaker meta = MetaData() org_table = Table( "organizations", meta, Column("org_id", Integer, primary_key=True), Column("org_name", String(50), nullable=False, key="name"), mysql_engine="InnoDB", ) member_table = Table( "members", meta, Column("member_id", Integer, primary_key=True), Column("member_name", String(50), nullable=False, key="name"), Column( "org_id", Integer, ForeignKey("organizations.org_id", ondelete="CASCADE"), ), mysql_engine="InnoDB", ) class Organization(object): def __init__(self, name): self.name = name class Member(object): def __init__(self, name): self.name = name mapper( Organization, org_table, properties={ "members": relationship( Member, # Organization.members will be a Query object - no loading # of the entire collection occurs unless requested lazy="dynamic", # Member objects "belong" to their parent, are deleted when # removed from the collection cascade="all, delete-orphan", # "delete, delete-orphan" cascade does not load in objects on # delete, allows ON DELETE CASCADE to handle it. # this only works with a database that supports ON DELETE CASCADE - # *not* sqlite or MySQL with MyISAM passive_deletes=True, ) }, ) mapper(Member, member_table) if __name__ == "__main__": engine = create_engine( "postgresql://scott:tiger@localhost/test", echo=True ) meta.create_all(engine) # expire_on_commit=False means the session contents # will not get invalidated after commit. sess = sessionmaker(engine, expire_on_commit=False)() # create org with some members org = Organization("org one") org.members.append(Member("member one")) org.members.append(Member("member two")) org.members.append(Member("member three")) sess.add(org) print("-------------------------\nflush one - save org + 3 members\n") sess.commit() # the 'members' collection is a Query. it issues # SQL as needed to load subsets of the collection. print("-------------------------\nload subset of members\n") members = org.members.filter(member_table.c.name.like("%member t%")).all() print(members) # new Members can be appended without any # SQL being emitted to load the full collection org.members.append(Member("member four")) org.members.append(Member("member five")) org.members.append(Member("member six")) print("-------------------------\nflush two - save 3 more members\n") sess.commit() # delete the object. Using ON DELETE CASCADE # SQL is only emitted for the head row - the Member rows # disappear automatically without the need for additional SQL. sess.delete(org) print( "-------------------------\nflush three - delete org, " "delete members in one statement\n" ) sess.commit() print("-------------------------\nno Member rows should remain:\n") print(sess.query(Member).count()) sess.close() print("------------------------\ndone. dropping tables.") meta.drop_all(engine)