如何提高包含SQLAlchemy查询语句的循环速度

3 投票
2 回答
3470 浏览
提问于 2025-04-15 21:23

这个循环的作用是检查某个记录是否在sqlite数据库里,然后为那些缺失的记录创建一个字典列表,最后用这个列表执行一次批量插入的操作。这个方法是可行的,但速度非常慢(至少我觉得很慢),因为处理3500个查询需要花费5分钟。我对python、sqlite和sqlalchemy完全是个新手,所以我在想有没有更快的方法来完成这个任务。

list_dict = []

session = Session()

for data in data_list:
    if session.query(Class_object).filter(Class_object.column_name_01 == data[2]).filter(Class_object.column_name_00 == an_id).count() == 0:
        list_dict.append({'column_name_00':a_id,
                          'column_name_01':data[2]})

conn = engine.connect()
conn.execute(prices.insert(),list_dict)
conn.close()
session.close()

编辑:我把session = Session()移到了循环外面,但没有什么变化。

解决方案

感谢mcabral的回答,我对代码进行了修改:

existing_record_list = []
list_dict = []

conn = engine.connect()
s = select([prices.c.column_name_01], prices.c.column_name_00==a_id)
result = conn.execute(s) 
for row in result:       
    existing_record_list.append(row[0])

for data in raw_data['data']:
    if data[2] not in existing_record_list:
        list_dict.append({'column_name_00':a_id,
                          'column_name_01':data[2]}

conn = engine.connect()
conn.execute(prices.insert(),list_dict)
conn.close()

现在只需要6秒。这真是个很大的进步!!

2 个回答

0

很高兴你找到了解决办法,顺便说几句:

我同意mcabral的看法。一般来说,如果你在一个循环里放了查询,那就很可能会出问题。常见的SQL数据库通常是为了快速获取数据而优化的。把查询放在循环里,通常意味着你在做一些本可以用一个查询或者一串查询来完成的事情。

当然也有例外,但根据我的经验,这种情况通常很少见……每次我在循环中运行查询,最后都后悔了。

3

3500个查询听起来确实很多。

你有没有考虑过一次性获取所有的数据?这样的话,你就可以在内存中遍历一个列表,而不是每次都去数据库查询每一项。

撰写回答