私はPythonとsqlalchemyが初めてです。where条件を手動で作成すると、すでにdeleteメソッドが機能しています。ここで、yaml形式のenterリクエストから列と値を読み取り、where条件を作成する必要があります。
#enter data as yaml
items:
- item:
table: [MyTable,OtherTable]
filters:
field_id: 1234
#other_id: null
これが私が試みて先に進めないことです:
for i in use_case_cfg['items']:
item = i.get('item')
for t in item['table']:
if item['filters']:
filters = item['filters']
where_conditions = ''
count = 0
for column, value in filters.items():
aux = str(getattr(t, column) == bindparam(value))
if count == 0:
where_conditions += aux
else:
where_conditions += ', ' + aux
count += 1
to_delete = inv[t].__table__.delete().where(text(where_conditions))
#to_delete = t.__table__.delete().where(getattr(t, column) == value)
else:
to_delete = inv[t].__table__.delete()
CoreData.session.execute(to_delete)
私には問題ないように見えますが、実行すると次のエラーが発生します:sqlalchemy.exc.StatementError:(sqlalchemy.exc.InvalidRequestError)バインドパラメーター「9876」に値が必要です[SQL:DELETE FROM MyTable
WHERE "MyTable" .field_id =%(1234)s] [parameters:[{}]](このエラーの背景:http://sqlalche.me/e/cd3x)
誰かが私に何が間違っているのか、それを行う適切な方法を説明できますか?ありがとう。
コードには2つの問題があります。
まず、
str(getattr(t, column) == bindparam(value))
プレースホルダーとして値をバインドしているため、
WHERE f2 = :Bob
しかし、それはの値にマップされる名前でなければならないfilters
ので(あなたの場合は列名)、最終的には
WHERE f2 = :f2
次に、複数のWHERE
条件がコンマで結合されていますが、実行しようとしていることに応じて、AND
またはを使用する必要がありますOR
。
与えられたモデルFoo
:
class Foo(Base):
__tablename__ = 'foo'
id = sa.Column(sa.Integer, primary_key=True)
f1 = sa.Column(sa.Integer)
f2 = sa.Column(sa.String)
コードのセグメントの動作バージョンは次のとおりです。
filters = {'f1': 2, 'f2': 'Bob'}
t = Foo
where_conditions = ''
count = 0
for column in filters:
aux = str(getattr(t, column) == sa.bindparam(column))
if count == 0:
where_conditions += aux
else:
where_conditions += ' AND ' + aux
count += 1
to_delete = t.__table__.delete().where(sa.text(where_conditions))
print(to_delete)
session.execute(to_delete, filters)
WHERE
条件を文字列として作成する義務がない場合は、次のように実行できます。
where_conditions = [(getattr(t, column) == sa.bindparam(column))
for column in filters]
to_delete = t.__table__.delete().where(sa.and_(*where_conditions))
session.execute(to_delete, filters)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加