【发布时间】:2021-01-15 04:02:29
【问题描述】:
我有一个带有复合主键的模型 我正在尝试使用 sqlalchemy 的 merge() 方法执行 upsert。 出于某种原因,它在我的其他测试模型上运行良好(复合键总共由 7 个列组成),但在这个模型上却很难通过
class Offsets(db.Model, CommonMethods):
symbol_id = db.Column(db.String(120), primary_key=True)
account_id = db.Column(db.String(120), primary_key=True)
settlement_counterparty = db.Column(db.String(120), primary_key=True)
execution_counterparty = db.Column(db.String(120), primary_key=True)
counterparty_account_id = db.Column(db.String(120))
trade_date = db.Column(db.String(10), primary_key=True)
daily_diff = db.Column(db.String(120))
buy_qty = db.Column(db.String(120))
sell_qty = db.Column(db.String(120))
pos_before_trade = db.Column(db.String(120))
pos_after_trade = db.Column(db.String(120))
offset = db.Column(db.String(120))#resulting offset
related_orders = db.Column(db.ARRAY(db.String(360)))
comment = db.Column(db.String(360))
manual = db.Column(db.Boolean, default=False, primary_key=True)
settlement = db.Column(db.Boolean, default=False, primary_key=True) #for some reason if i remove this from model, merging goes fine
下面我正在尝试执行 upsert
app=create_app()
app.app_context().push()
entry=Offsets(
trade_date='2020-09-29',
symbol_id='AAPL',
account_id='FOO',
buy_qty='0',
settlement_counterparty='BAR',
execution_counterparty='BAZ',
counterparty_account_id='FOOBARBAZ',
sell_qty='1',
daily_diff='1',
related_orders=['some_uuids_here'],
manual=False
)
db.session.merge(entry)
<Offsets (transient 140184049284712)>
db.session.commit()#first went fine as it wasnt in db
None
db.session.merge(entry)
<Offsets (transient 140184049535072)>
db.session.commit()#second time it returns an error though
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/scoping.py", line 162, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/session.py", line 1027, in commit
self.transaction.commit()
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/session.py", line 492, in commit
self._assert_active(prepared_ok=True)
File "/usr/local/lib/python3.6/dist-packages/sqlalchemy/orm/session.py", line 295, in _assert_active
code="7s2a",
sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint "offsets_pkey"
DETAIL: Key (symbol_id, account_id, settlement_counterparty, execution_counterparty, trade_date, manual, settlement)=(AAPL, FOO, BAR, BAZ, 2020-09-29, f, f) already exists.
上面的代码不应该在没有错误的情况下执行 upsert(在冲突时更新非主键 cols)吗?
【问题讨论】:
标签: python merge sqlalchemy upsert