【问题标题】:Save or update for FK relationship Sqlalchemy保存或更新 FK 关系 Sqlalchemy
【发布时间】:2011-01-21 18:14:34
【问题描述】:

我在谷歌上搜索过,但无法找到这个看似简单的问题的答案。

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

假设我创建了一个新的订单实例并为该订单设置了一个客户。比如:

order_instance.customer = Customer("customer name")

当我保存订单实例时,如果客户表中已经存在同名客户,SqlAlchemy 会报错。

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

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

似乎 SqlAlchemy,无论客户是否已经存在,都在尝试向客户表执行 SQL 插入语句。 也许我的级联设置不正确?

【问题讨论】:

    标签: foreign-keys sqlalchemy


    【解决方案1】:

    这是我通常的做法:

    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__ 方法来执行此操作。但是我建议不要这样做,因为最好清楚你在做什么。

    【讨论】:

    • 我不明白你的例子——你的方法没有返回一个对象。如果客户已经存在于数据库中,这将如何工作?
    • 如果客户存在,这不会更新客户记录。
    【解决方案2】:

    我无法发表评论,但要添加到 Singletoned 的答案。

    对于每个要创建的客户,您只能调用一次该函数。 IE。你不能这样使用它:

    .. = 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() 处理客户

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      • 2021-01-04
      • 1970-01-01
      • 2012-09-29
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      相关资源
      最近更新 更多