我想使用PostgreSQL 9.5添加的“新”功能,使用SQLAlchemy Core进行upsert操作。虽然它已经实现了,但是我对语法感到很困惑,我无法使其符合我的需求。 以下是一个示例代码,我希望能够执行:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'test'
a_id = Column('id',Integer, primary_key=True)
a = Column("a",Integer)
engine = create_engine('postgres://name:password@localhost/test')
User().metadata.create_all(engine)
meta = MetaData(engine)
meta.reflect()
table = Table('test', meta, autoload=True)
conn = engine.connect()
from sqlalchemy.dialects.postgresql import insert as psql_insert
stmt = psql_insert(table).values({
table.c['id']: bindparam('id'),
table.c['a']: bindparam('a'),
})
stmt = stmt.on_conflict_do_update(
index_elements=[table.c['id']],
set_={'a': bindparam('a')},
)
list_of_dictionary = [{'id':1, 'a':1, }, {'id':2, 'a':2,}]
conn.execute(stmt, list_of_dictionary)
我想插入一组行,如果其中一个ID已经存在,则希望使用我最初要插入的值进行更新。然而,SQLAlchemy抛出了以下错误:CompileError: bindparam() name 'a' is reserved for automatic usage in the VALUES or SET clause of this insert/update statement. Please use a name other than column name when using bindparam() with insert() or update() (for example, 'b_a').
虽然这是一个已知的问题(请参见https://groups.google.com/forum/#!topic/sqlalchemy/VwiUlF1cz_o), 但我没有找到任何不需要修改list_of_dictionary的键或列名的适当答案。
我想知道是否有一种构建stmt的方法,以便具有一致的行为,不依赖于变量list_of_dictionary的键是否是插入表的列名(在这些情况下,我的代码可以正常运行而不出错)。
execute(query)
一起工作吗?query
在任何地方都没有定义。它应该是execute(update_stmt)
吗? - zebrainatreeinsert_ignore
是什么,我在你的导入中没有看到这个函数,另外records
是什么?它是一个列表还是一个字典? - spitfireddinsert_ignore()
是在文件中定义的一个函数,它会忽略而不是更新冲突的行。records
是一个字典列表。 - ryantuck