私は、postgresql 9.5で追加された "新しい"機能を使用して、sqlalchemy coreを使用してアップサイトを行いたいと思います。それが実装されている間、私はかなり私のニーズに適応できない構文に混乱しています。ここ は私が行うことができるようにしたいもののサンプルコードです:postgresqlでsqlalchemyを使って適切なアップサンプリングを行うにはどうすればよいですか?
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:[email protected]/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)
私はbasicly行の大部分を挿入すると、1つのIDがすでに使用されている場合、私は値でそれを更新したいです私はinitinalyが挿入したかった。 しかし私は、このエラーをスロー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のキーまたはあなたの名前のいずれかを変更する必要はありません任意の適切な答えを見つけることができませんでした列。
変数list_of_dictionaryのキーが挿入されたテーブルの列の名前であるかどうかに依存しない、一貫した動作を行う方法でstmtを構築する方法があるかどうかを知りたいのですがこれらの場合は間違いなく)。
は、私は必要なものであるstmt.excludedを、知っていませんでした。私は他の手であなたがプライマリキーを除外しようとしている理由を知りません、set = {cname:c for c stmt.excluded}は意図したとおりに動作するようです(プライマリを "更新"しても構いませんキー、それは定義上同じ値です) – Trolin
ああ、それは良い点です。コードを少なくとももう少しエレガントにするでしょう。 –
これは 'execute(query)'で動作しますか? 'query'はどこにも定義されません。それは 'execute(update_stmt)'でしょうか? – zebrainatree