如何在sqlalchemy上映射一对多关系

How to map one-to-many relationship on sqlalchemy

我正在学习 flask+sqlalchemy,但我在使用 ORM 时遇到了一些问题。我有一个 model.py 有一个 class House 和一个 class Member.

class House:

    def __init__(self, members: typing.Set['Member'] = None) -> None:
        if not patients:
            self.member = set()
        else:
            self.member = set(member)

    def add_member(self, person: 'Patient'):
        self.patients.add(person)

    def remove_member(self, patient: 'Member'):
        self.member.remove(patient)

class Member:

    def __init__(self, first_name: str, email: str, phone: str, age: int, gender: str, last_name=None) -> None:
        self.first_name = first_name
        self.last_name = last_name
        self.email = email
        self.phone = phone
        self.age = age
        self.gender = gender

    def __hash__(self) -> int:
        return hash(self.email)

    def __eq__(self, other):
        if isinstance(other, Patient):
            return self.email == other.email
        return NotImplemented

orm.py 我有:

house = Table(
    'house', metadata,
    Column('id', INTEGER, primary_key=True, autoincrement=True)
)

member = Table(
    'patient', metadata,
    Column('id', INTEGER, primary_key=True, autoincrement=True),
    Column('first_name', String(255)),
    Column('last_name', String(255)),
    Column('email', String(255)),
    Column('phone', String(255)),
    Column('age', INTEGER),
    Column('gender', String(255)),

member_allocation = Table(
    'patient_allocation', metadata,
    Column('id', INTEGER, primary_key=True, autoincrement=True),
    Column('member_id', ForeignKey('member.id')),
    Column('house_id', ForeignKey('house.id')),
)

def start_mappers():
    member_mapper = mapper(model.Member,member)
    house_mapper = mapper(
        model.House,
        house,
        properties={
            'members': relationship(
                member_mapper,
                secondary=member_allocation,
                collection_class=set,
                backref=backref('house')),
        })

一个房子可以有很多成员,一个成员只能有一个房子。我觉得我不需要 member_allocation table。我觉得很简单,在 member table 上有一个 house_id 作为外键('house.id')就足够了,而且 member_mapper 必须是这样的:

member_mapper = mapper(
    model.Member,
    member,
    properties={'house': relationship(house_mapper)
})

但如果我理解正确,properties 字典中的键(上面代码中的 house)必须是映射的 class 的属性。在我的例子中 house 不是 member class.

的属性

我哪里错了?

backref 属性 membershouse 都应由 SQLAlchemy 创建和填充。

你说得对,如果每个成员只能拥有一个房子,那么你就不需要协会 table(因为它是 one2many)。对于 many2many,您需要 table。您应该可以这样做(将 house_id 列移至成员 table):

def start_mappers():
    member_mapper = mapper(model.Member,member)
    house_mapper = mapper(model.House,
        house,
        properties={
            'members': relationship(
                member_mapper,
                collection_class=set,
                backref=backref('house')),
        })