SQLAlchemy - 如何正确连接两组数据?

SQLAlchemy - How to correctly connect two sets of data?

我希望得到一些指导,关于我认为 Python 的 SQLAlchemy 中的常见模式。但是,到目前为止,我还没有找到对 SQLAlchemy 新手的简单解释。

我有以下对象:

我正在构建一个 Python FastAPI 应用程序,我希望能够单独创建客户和产品。随后,我希望能够为可以包含 1 种或多种产品的客户创建订单。一个客户也可以有多个订单。

这是我的 SQLAlchemy 模型:

order_products = Table('order_products', Base.metadata,
    Column('order_id', ForeignKey('orders.id'), primary_key=True),
    Column('product_id', ForeignKey('products.id'), primary_key=True)
)

class Customer(Base):
    __tablename__ = "customers"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    address = Column(String)
    phonenumber = Column(String)
    email = Column(String, unique=True, index=True)
    is_active = Column(Boolean, default=True)

    orders = relationship("Order", back_populates="customers")

class Order(Base):
    __tablename__ = "orders"

    id = Column(Integer, primary_key=True, index=True)
    ordernumber = Column(String, index=True)
    customer_id = Column(Integer, ForeignKey("customers.id"))

    customers = relationship("Customer", back_populates="orders")
    products = relationship("Product", secondary="order_products", back_populates="orders")

class Product(Base):
    __tablename__ = "products"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, index=True)
    size = Column(Integer)
    order_id = Column(Integer, ForeignKey("orders.id"))

    orders = relationship("Order", secondary="order_products", back_populates="products")

这是我的 CRUD 操作:

def create_customer(db: Session, customer: customer.CustomerCreate):
    db_customer = models.Customer(name = customer.name, address = customer.address, email=customer.email, phonenumber=customer.phonenumber)
    db.add(db_customer)
    db.commit()
    db.refresh(db_customer)
    return db_customer

def create_product(db: Session, product: product.Productreate):
    db_product = models.Product(name = product.name, size = product.size)
    db.add(db_product)
    db.commit()
    db.refresh(db_product)
    return db_product

def create_order(db: Session, order: order.OrderCreate, cust_id: int):
    db_order = models.Order(**order.dict(), customer_id=cust_id)
    db.add(db_order)
    db.commit()
    db.refresh(db_order)
    return db_order

def update_order_with_product(db: Session, order: order.Order):

    db_order = db.query(models.Order).filter(models.Order.id==1).first()
    if db_order is None:
        return None

    db_product = db.query(models.Order).filter(models.Product.id==1).first()
    if db_order is None:
        return None

    db_order.products.append(db_product)

    db.add(db_order)
    db.commit()
    db.refresh(db_order)
    return db_order

update_order_with_product 之外的所有 CRUD 操作都会给我这个错误:

child_impl = child_state.manager[key].impl KeyError: 'orders'

  1. 我不确定我是否采用了正确的方法来处理定义模型之间关系所需的模式。如果没有,有人可以为我指出一些适合初学者的好例子的正确方向吗?

  2. 如果我的模式有效,那么我尝试创建关系的 CRUD 操作一定有问题?有人可以帮忙吗?

这个查询可能有问题:

db_product = db.query(models.Order).filter(models.Product.id==1).first()

大概应该是:

db_product = db.query(models.Product).filter(models.Product.id==1).first()

因为您想获得一个 Product 实例,而不是 Order

当你更新一条记录时,你不应该将它添加到会话中(因为它在你查询记录时已经注册到会话中)。

def update_order_with_product(db: Session, order: order.Order):

    db_order = db.query(models.Order).filter(models.Order.id==1).first()
    if db_order is None:
        return None

    db_product = db.query(models.Product).filter(models.Product.id==1).first()
    if db_product is None:
        return None

    db_order.products.append(db_product)

    db.commit()
    db.refresh(db_order)
    return db_order