我读了很多资源(ao。 1, 2)但是我无法在sqlalchemy中使用Postgresql的ON CONFLICT IGNORE行为。
我用过 这个接受的答案 作为基础,但它给出了
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
PS。使用python 2.7(不介意升级到3.4 / 3.5),最新的sqlalchemy(1.x)
你不需要这个,使用存在条件来防止插入重复。
例如:
INSERT INTO table (unique_name)
SELSCT 'some_string'
WHERE NOT EXISTS(SELECT 1 FROM table WHERE unique_name = 'some_string')
你也可以
INSERT INTO table (unique_name)
VALUES('some_string')
ON CONFLICT (unique_name) DO NOTHING
但如果你需要 插 或者在单个查询中更新,那么这是您的示例:
INSERT INTO distributors (did, dname)
VALUES (5, 'Gizmo Transglobal'), (6, 'Associated Computing, Inc')
ON CONFLICT (did) DO UPDATE SET dname = EXCLUDED.dname;
这是PostgreSQL文档中的示例。
使用Postgres 9.6.1,sqlachemy 1.1.4和psycopg2 2.6.2:
将数据结构转换为字典。从熊猫那里来的
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')
通过sqlalchemy连接到数据库
engine = sqlalchemy.create_engine("postgresql://user:password@localhost/postgres")
connect = engine.connect()
meta = MetaData(bind=engine)
meta.reflect(bind=engine)
构造一个插入语句 db table
叫 tstbl
table = meta.tables['tstbl']
insrt_stmnt = insert(table).values(insrt_vals)
# Where colA and colB are the columns to check for the conflict
do_nothing_stmt = insrt_stmnt.on_conflict_do_nothing(index_elements=['colA','colB'])
执行
results = engine.execute(do_nothing_stmt)
# Get number of rows inserted
rowcount = results.rowcount
警告:
此方法不起作用 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)
这适用于Postgresql 9.5:
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def prefix_inserts(insert, compiler, **kw):
return compiler.visit_insert(insert, **kw) + " ON CONFLICT DO NOTHING"
我用它 bulk_insert_mappings
。然而它确实没有 ON CONFLICT DO NOTHING
可选的