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

Posted

技术标签:

【中文标题】为啥我的 IdentitySet 只显示最后一项?【英文标题】:Why is my IdentitySet only showing the last item?为什么我的 IdentitySet 只显示最后一项? 【发布时间】:2021-05-18 07:23:22 【问题描述】:

我有一个熊猫系列并遍历所有项目。每个循环我检查一个条目是否已经存在,如果没有找到条目,则将它们一一添加到 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

【问题讨论】:

你能添加一个系列的 var 转储吗? 添加了一些虚拟数据和导入语句 如果您在拨打len(session.new) 后立即print(session.new),您会看到什么? 我无法重现您的问题。 This code 对我来说很好。 是的,你的权利!我再次对其进行了测试,它按预期工作。问题似乎是第一个查询,我将其注释掉,因为我认为这不会是问题......在向会话添加警报并随后在下一个循环中将警报设置为 None 之后似乎是问题。 【参考方案1】:

所以问题似乎是在将其添加到会话后您无法覆盖相同的变量。

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,有没有更好的方法?

【讨论】:

【参考方案2】:

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

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

【讨论】:

以上是关于为啥我的 IdentitySet 只显示最后一项?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ListActivity 不显示 ArrayAdapter 中的最后一项?

Listview一遍又一遍地只显示最后一项

NSPredicate/TableView 只显示一项,为啥?

android - json 生成的 listview onClick 只显示最后一项

RecyclerView 只显示一项

Core Data 只保存最后一项