如何使用经典映射使用SQLAlchemy初始化多对多类

时间:2016-10-03 12:25:15

标签: sqlalchemy many-to-many

我正在使用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中使用属性,但我不确定如何。

1 个答案:

答案 0 :(得分:0)

您未正确使用经典映射。有关完整示例,请参阅documentation。特别是,您不能在类本身内声明任何关系或列。正确的咒语是:

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')
})