【问题标题】:Sqlalchemy upsert on conflict on postgresqlSqlalchemy upsert 关于 postgresql 上的冲突
【发布时间】:2021-08-05 13:44:36
【问题描述】:

在 postgres 中插入数据时我会忽略重复键 我的表对 3 列有唯一约束。现在我在下面发布的代码仅适用于 primary_key 但不适用于唯一约束。有人有建议吗?
谢谢 E

            @compiles(Insert)
            def _prefix_insert_with_ignore(insert_srt, compiler, **kw):

                conn = Connection()
                conn_str = conn.conn_str()
                test_conn = conn_str.find("sqlite")
                if test_conn == 0:
                    return compiler.visit_insert(insert_srt.prefix_with('OR IGNORE'), **kw)
                else:
                    #if the connection is postgresql
                    pk = insert_srt.table.primary_key
                    insert = compiler.visit_insert(insert_srt, **kw)
                    ondup = f"ON CONFLICT ({','.join(c.name for c in pk)}) DO NOTHING"
                    
                    upsert = ' '.join((insert, ondup))
                    return upsert

【问题讨论】:

  • 难道INSERT…ON CONFLICT (Upsert) 不是postgresql 版本的解决方案,甚至不需要自定义编译吗?
  • 如果你确实需要支持2种不同的RDBMS并且你确实觉得你需要实现自定义编译,我也建议你使用Dialect-specific compilation rules
  • 我试图这样做 uk=insert_srt.table.constraints ondup = f"ON CONFLICT ({','.join(str(c.colums) for c in uc)}) DO NOTHING" .我有唯一约束和主键约束的列表。所以我只需要唯一约束列。我该怎么办?
  • 您可能想要c = next(x for x in products.constraints if isinstance(x, sa.UniqueConstraint))column_names = [col.name for col in c.columns] 之类的东西?
  • @snakecharmerb 非常感谢,效果很好

标签: database postgresql sqlalchemy bulkinsert upsert


【解决方案1】:

好的,这对我很有效

非常感谢@snakechrmerb

            @compiles(Insert)
            def _prefix_insert_with_ignore(insert_srt, compiler, **kw):

                conn = Connection()
                conn_str = conn.conn_str()
                test_conn = conn_str.find("sqlite")
                if test_conn == 0:
                    return compiler.visit_insert(insert_srt.prefix_with('OR IGNORE'), **kw)
                else:
                    #if the connection is postgresql
                    ck = insert_srt.table.constraints
                    pk = insert_srt.table.primary_key
                    insert = compiler.visit_insert(insert_srt, **kw)
                    c = next(x for x in ck if isinstance(x, sa.UniqueConstraint))
                    column_names = [col.name for col in c.columns]
                    s= ", ".join(column_names)
                    ondup = f'ON CONFLICT ({s})DO NOTHING'
                
                    upsert = ' '.join((insert, ondup))
                    return upsert

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-17
    • 2022-01-01
    • 2016-11-01
    • 2017-06-03
    • 1970-01-01
    • 2023-04-06
    • 2018-04-12
    • 2019-08-15
    相关资源
    最近更新 更多