Code: Select all
import sqlalchemy as sqal
client_group_association = sqal.Table(
"client_group_association",
Base.metadata,
sqal.Column("client_id", sqal.UUID, sqal.ForeignKey("client_info.id"), primary_key=True),
sqal.Column("group_id", sqal.UUID, sqal.ForeignKey("group_info.id"), primary_key=True)
)
class ClientInfo(Base):
"""Stores information of clients."""
__tablename__ = "client_info"
id: Mapped[uuid6.UUID] = mapped_column(sqal.UUID(as_uuid=True), primary_key=True,
insert_default=uuid6.uuid7())
name: Mapped[str] = mapped_column(sqal.String, nullable=False)
email: Mapped[str] = mapped_column(sqal.String, nullable=False)
phone: Mapped[str] = mapped_column(sqal.String, nullable=False)
age: Mapped[int] = mapped_column(sqal.Integer, nullable=False)
# Other unrelated fields
groups: Mapped[List[uuid6.UUID]] = mapped_column(UUIDList, nullable=True)
group_objs: Mapped[List["GroupInfo"]] = relationship(
secondary=client_group_association,
back_populates="client_objs"
)
__table_args__ = (sqal.UniqueConstraint('name', 'email', 'phone', name='_unique_client_details'),
sqal.ForeignKeyConstraint(['groups'], ['group_info.id'],
onupdate='CASCADE', ondelete='CASCADE'))
class GroupInfo(Base):
"""Stores information of groups."""
__tablename__ = "group_info"
id: Mapped[uuid6.UUID] = mapped_column(sqal.UUID(as_uuid=True), primary_key=True,
insert_default=uuid6.uuid7())
location: Mapped[Locations] = mapped_column(sqal.Enum(Locations), nullable=False)
members: Mapped[List[uuid6.UUID]] = mapped_column(UUIDList, nullable=True)
client_objs: Mapped[List["ClientInfo"]] = relationship(
secondary=client_group_association,
back_populates="group_objs"
)
__table_args__ = (sqal.UniqueConstraint('members', name='_unique_members'),
sqal.ForeignKeyConstraint(['members'], ['client_info.id'],
onupdate='CASCADE', ondelete='CASCADE'))
Session = sessionmaker(bind=self.__SQL_ENGINE, class_=AsyncSession)
if locked:
async with self.__LOCK:
async with Session() as session:
yield session
else:
async with Session() as session:
yield session
< /code>
Die Dinge schienen eine Weile zu funktionieren; Ich könnte die verschachtelten Objekte mit verschachtelten SelectInLoad [/code] Anweisungen abrufen:
Code: Select all
stmt = select(ClientInfo).where(...)\
.limit(10)\
.options(selectinload(ClientInfo.group_objs)\
.selectinload(GroupInfo.client_objs)) # Force eager-loading
< /code>
Jedes Mal, wenn ich eine neue Gruppe erstellen möchte, bin ich jetzt mit < /p>
richtsqlalchemy.exc.InvalidRequestError: Can't attach instance ; another instance with key (, (UUID('019634d4-1422-7a0e-9a21-96941acc10dd'),), None) is already present in this session.
Beachten Sie, dass ich jedes Mal, wenn ich auf die Datenbank zugreifen möchte, eine neue Sitzung erstelle. Dies ist der wichtigste Teil der Transaktion, da ich in Zukunft auf die Client-Objekte in dieser Beziehung beziehe.
Code: Select all
group_info: GroupInfo = GroupInfo(id=uuid6.uuid7(),
location=self.location,
members=list(self.clients.keys()))
for client_info in self.clients.values():
group_info.client_objs.append(client_info)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
Code: Select all
session.expunge(client_info)
session.expire(client_info)