Различия между отношениями SQLAlchemy - PullRequest
1 голос
/ 10 октября 2019

Будучи новичком в SQLAlchemy и SQL, отношения в SQLAlchemy меня смущают.

Является ли этот набор определений модели SQLAlchemy (основанный на один-ко-многим в официальных документах )

class Invoice(Base):
    __tablename__ = 'invoices'
    id = Column(Integer, primary_key=True)
    customer = relationship("Customer")

class Customer(Base):
    __tablename__ = 'customers'
    id = Column(Integer, primary_key=True)
    invoice_id = Column(Integer, ForeignKey('invoices.id'))

идентично

class Invoice(Base):
    __tablename__ = 'invoices'
    id = Column(Integer, primary_key=True)

class Customer(Base):
    __tablename__ = 'customers'
    id = Column(Integer, primary_key=True)
    invoice_id = Column(Integer, ForeignKey('invoices.id'))
    invoice = relationship("Invoice")

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

В чем разница между ними?

1 Ответ

2 голосов
/ 11 октября 2019

Каждая из этих моделей совпадает с таблицами и столбцами в базе данных. Разница заключается в том, как вы используете директиву relationship(), которая позволяет ORM взаимодействовать с отношением внешнего ключа между этими таблицами. Я должен отметить, что вам вообще не нужно создавать эти атрибуты отношений, если вам не нужна / не требуется дополнительная помощь ORM во взаимодействии с этими отношениями между таблицами.

В первом примере высоздание атрибута customer для Invoice, который позволит вам выполнять такие действия, как доступ ко всем клиентам, связанным с конкретным счетом. Например, вы можете напечатать каждый идентификатор клиента, связанный с конкретным счетом.

invoice = session.query(Invoice).filter(Invoice.id == 1).first()
for c in invoice.customer:
    print(c.id)

Во втором примере вы создаете атрибут invoice для Customer, который позволит вам выполнять такие действия, как доступданные счета, связанные с конкретным клиентом. Например, вы можете напечатать идентификатор счета клиента (это было бы более полезно, если бы у вас были другие столбцы Invoice, на которые еще не ссылался внешний ключ в Customer).

customer = session.query(Customer).filter(Customer.id == 1).first()
print(customer.invoice.id)

Если вы хотите получить доступ к этим атрибутам с обеих сторон отношения, чтобы вы могли использовать ORM обоими способами, описанными выше (среди прочих), вы можете использовать либоback_populates или backref параметры для соединения двух отношений. Вы можете узнать больше об этих опциях в Связывание отношений с Backref .

class Invoice(Base):
    __tablename__ = 'invoices'
    id = Column(Integer, primary_key=True)
    customers = relationship("Customer", back_populates="invoice")

class Customer(Base):
    __tablename__ = 'customers'
    id = Column(Integer, primary_key=True)
    invoice_id = Column(Integer, ForeignKey('invoices.id'))
    invoice = relationship("Invoice", back_populates="customers") 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...