Python 炼金术关系之间的差异

Python 炼金术关系之间的差异,python,sql,sqlalchemy,Python,Sql,Sqlalchemy,作为SQLAlchemy和SQL的新手,SQLAlchemy中的关系让我感到困惑 这是一组SQLAlchemy模型定义(基于) 等同于 class Invoice(Base): __tablename__ = 'invoices' id = Column(Integer, primary_key=True) class Customer(Base): __tablename__ = 'customers' id = Column(Integer, primary

作为SQLAlchemy和SQL的新手,SQLAlchemy中的关系让我感到困惑

这是一组SQLAlchemy模型定义(基于)

等同于

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")
我一直在使用第二种方法定义我的模型,到目前为止,它似乎工作得很好。然而,我不确定这是否是建立关系的正确方式


这两种模型之间的区别是什么?

就生成的数据库表和列而言,每种模型都是相同的。区别在于如何使用使ORM能够与这些表之间的外键关系交互的指令。我应该注意到,如果在与表之间的这些关系交互时不需要/不需要ORM的额外帮助,则根本不需要创建这些关系属性

在第一个示例中,您正在为
Invoice
创建一个
customer
属性,该属性允许您访问与特定发票关联的任何和所有客户。例如,您可以打印与特定发票关联的每个客户id

invoice = session.query(Invoice).filter(Invoice.id == 1).first()
for c in invoice.customer:
    print(c.id)
在第二个示例中,您正在为
Customer
创建一个
invoice
属性,该属性使您能够访问与特定客户关联的发票数据。例如,您可以打印客户的发票id(如果在
客户
中外键尚未引用其他
发票
列,这将更有用)

如果您希望访问关系两侧的这些属性,以便能够以上述两种方式(以及其他方式)使用ORM,则可以使用
back\u populates
backref
参数来连接这两个关系。有关这些选项的详细信息,请访问

relationship(“Invoice”)
用于ORM的对象端,
ForeignKey
用于关系端。
invoice = session.query(Invoice).filter(Invoice.id == 1).first()
for c in invoice.customer:
    print(c.id)
customer = session.query(Customer).filter(Customer.id == 1).first()
print(customer.invoice.id)
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")