为什么我的IdentitySet只显示最后一项?



我有一个pandas系列并遍历所有条目。在每个循环中,我检查条目是否已经存在,如果没有找到条目,则将它们逐一添加到sqlalchemy会话中。在循环完成后,我想检索在提交之前添加到会话的项的数量。然而,它只在IdentitySet中显示1项。当提交会话时,所有项都插入到我的数据库中。

from datetime import datetime
from pandas import Series
from random import randint
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from .models import Alarm
engine = create_engine(...)
session = Session(engine)
series = Series(data=[randint(1, 10**3) for i in range(0, 12)],
index=[datetime(2020, i, 1) for i in range(1, 13)])
series.count()  # Returns 12
for index, value in series.iteritems():
alarm = session.query(Alarm).filter_by(date=index.date()).first()  # Returns None
if alarm:
continue
alarm = Alarm(date=index.date(), value=value)
session.add(alarm)
len(session.new)  # Returns 1
session.commit()  # Inserts 12 entries to database

如果将echo=True添加到create_engine()调用中,并查看正在发出的SQL,您将注意到,在迭代循环时,将一行一行插入到表中。这是因为session.query()正在执行会话的隐式刷新,以确保它获得最新的信息(例如,在多用户环境中可能是必要的)。

因此所有12项都被插入,但是会话在给定时间内永远不会有超过一个的新元素。

所以问题似乎是你不能覆盖相同的变量添加到会话后。

alarm = Alarm(date=date(2020, 12, 31), value=123)
session.add(alarm)
len(session.new)  # Returns 1
alarm = None
len(session.new)  # Returns 0

所以这应该解决我的问题:

alarms = []
for index, value in series.iteritems():
alarm = session.query(Alarm).filter_by(date=index.date()).first()
if alarm:
continue
alarms.append(Alarm(date=index.date(), value=value))
session.add_all(alarms)

是否有更好的方法做到这一点,没有列表alarms?

相关内容

  • 没有找到相关文章

最新更新