Как работают простые отношения SQLAlchemy?

Я не эксперт по базам данных. На самом деле я просто знаю основы. Я выбрал SQLAlchemy для небольшого проекта, и я использую декларативную базовую конфигурацию, а не "обычный" способ. Этот способ кажется намного проще.

Однако при настройке моей схемы базы данных я понял, что не понимаю некоторые концепции отношений с базой данных.

Если раньше у меня было отношение "много-к-одному", например, статьи авторов (где каждая статья могла быть написана только одним автором), я бы поставил в столбце author_id поле author_id. Но SQLAlchemy имеет этот объект ForeignKey и функцию отношений с backref kwarg, и я понятия не имею, что из них имеет смысл.

Я боюсь узнать, как выглядит отношение "многие ко многим" с промежуточной таблицей (когда мне нужны дополнительные данные о каждой связи).

Может ли кто-то демистифицировать это для меня? Прямо сейчас я настраиваю разрешение 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')), но я не уверен - и мне нужно поместить openids = relationship("OpenID", backref="users") в класс Users? Зачем? Что оно делает? Что такое backref?

Ответ 1

Да, вам нужно user_id = Column(Integer, ForeignKey('users.id')) или user_id = Column(Integer, ForeignKey('users.id'), nullable=False), если это необходимо. Это напрямую переводится в FOREIGN KEY в базовой схеме базы данных, без магии.

Простым способом объявления отношения является user = relationship(Users) в классе OpenID. Вы также можете использовать users = relationship('OpenID') в классе Users. Параметр backref позволяет объявлять обе связи с одним объявлением: это означает автоматическую установку обратных отношений в связанном классе. Я лично предпочитаю использовать backref -s только для самостоятельных ссылок. Причина в том, что мне нравится самодокументированный код: когда вы просматриваете его определение, вы видите все определенные свойства, а при backref вам нужно просматривать другие классы (возможно, определенные в других модулях).