简单的SQLAlchemy关系是如何工作的?

30 投票
1 回答
11427 浏览
提问于 2025-04-15 23:13

我对数据库不是很懂,只知道一些基础知识。最近我在做一个小项目,使用了SQLAlchemy这个工具,我选择了声明式基础配置,而不是“正常”的方式。这样做起来感觉简单多了。

不过,在设置我的数据库结构时,我发现自己对一些数据库关系的概念并不太明白。

比如说,如果我之前有一个多对一的关系,比如文章和作者(每篇文章只能由一个作者写),我会在我的articles表里放一个author_id字段。但是SQLAlchemy有一个叫ForeignKey的东西,还有一个带有backref参数的关系函数,我完全不知道这些是什么意思。

我现在有点害怕去了解多对多的关系是怎样的,尤其是当我需要额外的数据来描述每个关系时。

有没有人能帮我解释一下这些?现在我正在为我的应用设置OpenID认证。所以我有这个:

from __init__ import Base
from sqlalchemy.schema import Column
from sqlalchemy.types import Integer, String

class Users(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String, unique=True)
    email = Column(String)
    password = Column(String)
    salt = Column(String)


class OpenID(Base):
    __tablename__ = 'openid'
    url = Column(String, primary_key=True)
    user_id = #?

我觉得?应该替换成Column(Integer, ForeignKey('users.id')),但我不太确定——我需要在Users类里加上openids = relationship("OpenID", backref="users")吗?为什么?这有什么作用?什么是backref?

1 个回答

46

是的,你需要写 user_id = Column(Integer, ForeignKey('users.id')),或者如果这个字段是必须的,可以写 user_id = Column(Integer, ForeignKey('users.id'), nullable=False)。这其实就是在数据库中建立一个外键,没有什么特别的地方。

要简单地声明关系,可以在 OpenID 类中写 user = relationship(Users)。在 Users 类中,你也可以写 users = relationship('OpenID')。使用 backref 参数可以让你用一行代码同时声明两个关系:这意味着在相关的类中会自动建立反向关系。我个人更喜欢只在自引用的关系中使用 backref。原因是我喜欢代码自解释:当你查看一个类的定义时,可以看到所有定义的属性,而使用 backref 时,你可能需要查看其他类(可能在其他模块中定义)。

撰写回答