Postgresql ON sqlalchemy 中的冲突

2024-03-22

我读过很多资源(ao.1 https://bitbucket.org/zzzeek/sqlalchemy/issues/3529/support-postgres-95-on-conflict-upserts, 2 https://stackoverflow.com/questions/17267417/how-do-i-do-an-upsert-merge-insert-on-duplicate-update-in-postgresql)但我无法让 Postgresql 的 ON CONFLICT IGNORE 行为在 sqlalchemy 中工作。

我用过这个接受的答案 https://stackoverflow.com/questions/6611563/sqlalchemy-on-duplicate-key-update作为基础,但它给出了

SAWarning: Can't validate argument 'append_string'; can't locate any SQLAlchemy dialect named 'append'

我尝试将 postgresql 方言添加到 @compile 子句中,重命名我的对象,但它不起作用。 我也尝试使用str(insert())+ " ON CONFILCT IGNORE"没有结果。 (顺便说一句,这并不奇怪)

我怎样才能得到On CONFLICT IGNORE添加到我的插入内容中?我喜欢所提出的解决方案,因为我可以看到自己不想要IGNORE每个人的行为INSERT

附:使用python 2.7(不介意升级到3.4/3.5),最新的sqlalchemy(1.x)


使用 Postgres 9.6.1、sqlachemy 1.1.4 和 psycopg2 2.6.2:

  1. 将您的数据结构转换为字典。来自熊猫它是

    import pandas
    from sqlalchemy import MetaData
    from sqlalchemy.dialects.postgresql import insert
    import psycopg2
    
    # The dictionary should include all the values including index values
    insrt_vals = df.to_dict(orient='records')
    
  2. 通过 sqlalchemy 连接到数据库。相反,请尝试下面的 psycog2 驱动程序和本机 COPY 函数,它会绕过所有 postgres 索引。

    csv_data = os.path.realpath('test.csv')
    con = psycopg2.connect(database = 'db01', user = 'postgres')
    cur = con.cursor()
    cur.execute("\copy stamm_data from '%s' DELIMITER ';' csv header" % csv_data)
    con.commit()
    
  3. Execute

    results = engine.execute(do_nothing_stmt)
    # Get number of rows inserted
    rowcount = results.rowcount
    

Warning:

此方法不适用于NaT开箱即用。

一切都在一起

tst_df = pd.DataFrame({'colA':['a','b','c','a','z', 'q'],
              'colB': pd.date_range(end=datetime.datetime.now() , periods=6),
              'colC' : ['a1','b2','c3','a4','z5', 'q6']})


insrt_vals = tst_df.to_dict(orient='records')
engine =      sqlalchemy.create_engine("postgresql://user:password@localhost/postgres")
connect = engine.connect()
meta = MetaData(bind=engine)
meta.reflect(bind=engine)
table = meta.tables['tstbl']
insrt_stmnt = insert(table).values(insrt_vals)

do_nothing_stmt  = insrt_stmnt.on_conflict_do_nothing(index_elements=['colA','colB'])
results = engine.execute(do_nothing_stmt)

代替步骤 2 和 3 ,使用psycog2对于较大的文件(接近一个 gig),使用 postgres 中的复制命令的驱动程序会更快,因为它会关闭所有表索引。

csv_data = os.path.realpath('test.csv')
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Postgresql ON sqlalchemy 中的冲突 的相关文章

随机推荐