代码之家  ›  专栏  ›  技术社区  ›  giser_yugang

如何使用pandas在SqlAlchemy中进行upsert

  •  1
  • giser_yugang  · 技术社区  · 6 年前

    我在postgresql中创建了一个表 SqlAlchemy :

    my_table = Table('test_table', meta,
                             Column('id', Integer,primary_key=True,unique=True),
                             Column('value1', Integer),
                             Column('value2', Integer)
                             )
    

       id  value1  value2
    0   1    32.0       1
    1   2     2.0      32
    2   3     NaN       3
    3   4   213.0      23
    

    我试着用我的代码 on_conflict_do_update 炼金术 具体如下:

    insert_statement = sqlalchemy.dialects.postgresql.insert(my_table,).values(df.to_dict(orient='records'))
    upsert_statement = insert_statement.on_conflict_do_update(
                                        index_elements=['id'],
                                        set_= df.to_dict(orient='dict')
                                    )
    conn.execute(upsert_statement)
    

    (psycopg2.ProgrammingError)无法适应“dict”类型

    我的SqlAlchemy版本是1.2.10,psycopg2版本是2.7.5。有人能帮我吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Ilja Everilä    6 年前

    这个 set_ 参数需要以列名作为键的映射,并且 ,但传递的是一个将嵌套字典作为值的映射,即。 df.to_dict(orient='dict') . 错误“can t adapt type'dict'”是SQLAlchemy将这些字典作为“文本”传递给Psycopg2的结果。

    因为您试图使用VALUES子句在一次插入中插入多行,所以应该使用 excluded 在集合动作中。EXCLUDED是表示要插入的行的特殊表。

    insert_statement = postgresql.insert(my_table).values(df.to_dict(orient='records'))
    upsert_statement = insert_statement.on_conflict_do_update(
        index_elements=['id'],
        set_={c.key: c for c in insert_statement.excluded if c.key != 'id'})
    conn.execute(upsert_statement)