如何使用 classical 映射使用 SQLAlchemy 初始化多对多 class

How to initialise a many-to-many class with SQLAlchemy using classical mapping

我正在使用 SQLAlchemy 并在父子之间建立多对多关系:

tables.py

parentLinkTable = Table('parent_links', metadata,
    Column('parent_id', BigInteger, ForeignKey('parent.id'), primary_key=True),
    Column('child_id', BigInteger, ForeignKey('child.id'), primary_key=True)
)

parentTable = Table('parent', metadata,
    Column('id', BigInteger, primary_key=True),
    Column('notes', Text)
)

childTable = Table('child', metadata,
    Column('id', BigInteger, primary_key=True),
    Column('notes', Text)
)

entities.py

class Parent():

    children = sqlalchemy.orm.relationship('Child', secondary=tables.parentLinkTable, back_populates='parents')


    def __init__(self, children: list, **kwargs):

        self.children = children

        for key, value in kwargs.items():
            setattr(self, key, value)

class Child():

    parents = sqlalchemy.orm.relationship('Parent', secondary=tables.parentLinkTable, back_populates='children')

    def __init__(self, **kwargs):

        for key, value in kwargs.items():
            setattr(self, key, value)

orm.py

import tables
import entities

sqlalchemy.orm.mapper(entities.Child, tables.childTable)
sqlalchemy.orm.mapper(entities.Parent, tables.parentTable)

application.py

children = session.query(Child).all()
parent = Cluster(children)
session.add(parent)
session.commit()

这段代码运行没有错误。但是,在保留新集群时,不会在 clusterLinkTable 上创建任何条目。我认为问题在于经典映射和声明映射的混合。我想我应该在 sqlalchemy.orm.mapper 中使用 properties,但我不确定如何使用。

您没有正确使用 classical 映射。请参阅 documentation 以获取完整示例。特别是,您不能在 class 本身内声明任何关系或列。正确的咒语是:

class Parent(object):
    def __init__(self, children: list, **kwargs):
        ...

class Child(object):
    def __init__(self, **kwargs):
        ...

sqlalchemy.orm.mapper(entities.Child, tables.childTable, properties={
    "parent": sqlalchemy.orm.relationship(entities.Parent, secondary=tables.parentLinkTable, back_populates='children')
})
sqlalchemy.orm.mapper(entities.Parent, tables.parentTable, properties={
    "children": sqlalchemy.orm.relationship(entities.Child, secondary=tables.parentLinkTable, back_populates='parents')
})