保存或更新FK关系Sqlalchemy

时间:2010-02-27 10:01:36

标签: foreign-keys sqlalchemy

我用Google搜索,但未能找到这个看似简单问题的答案。

我有两个关系,一个客户和一个订单。每个订单都与一个cusomter相关联,因此与客户表具有FK关系。客户关系仅存储客户名称,并且我在客户表上设置了一个唯一约束,禁止重复名称。

假设我创建了一个新订单实例并为订单设置了客户。类似的东西:

order_instance.customer = Customer("customer name")

当我保存订单实例时,如果客户表中已存在具有此名称的客户,SqlAlchemy将会抱怨。

如果具有此名称的客户尚不存在,或者只是忽略(甚至更新)客户关系,如何指定SqlAlchemy插入到客户表中?如果有名字的顾客已经存在,我真的不想每次检查......

---- ---编辑 Customer表上设置了唯一约束,因此没有两个客户可以使用相同的名称。 使用当前实现进行单点测试,会抛出IntegrityError。 如果已存在具有此名称的客户,请返回该客户实例。否则,返回一个新的Customer实例。

似乎SqlAlchemy,无论客户是否已经存在,都试图在Customer表中执行SQL insert语句。 也许我的瀑布设置不正确?

2 个答案:

答案 0 :(得分:3)

这是我通常的做法:

def get_or_create_customer(customer_name):
    customer = session.query(Customer).get(customer_name)
    if not customer:
       customer = Customer(customer_name)
    return customer

order_instance.customer = get_or_create_customer("Jeff Atwood")

您可以将此方法作为方法添加到您的课程中,或者您可以调整班级的__init__方法来执行此操作。但是我建议不要这样做,因为最好清楚一下你到底在做什么。

答案 1 :(得分:1)

我无法评论,但要添加单身人士的答案。

每个要创建的客户只能调用一次该函数。即你不能以这种方式使用它:

.. = get_or_create_customer(order[1].customer_name)
.. = get_or_create_customer(order[2].customer_name)
..
session.commit()

如果客户订购了多个订单并且客户尚未进入数据库,则会失败,因为它会尝试创建两个相同的客户。

修复该方案的许多方法......例如有一个insert_orders(..),它有get_or_create_customer作为嵌套函数,并使用set()处理客户