【发布时间】:2021-02-22 01:03:51
【问题描述】:
在 python 和 pandas 中使用 sqlite3 时出现意外错误。我正在使用 sqlite 数据库进行分析,因此它是单用户、单计算机。我在 Python 3.9.1 中,使用 sqlite 3.33.0 和 pandas 1.2.1。
简短的描述是,我正在尝试遍历Table1 的行,并且对于每一行,使用存储在Table1 中的ID 根据API 请求将数据插入Table2。 API 为我提供了比 Table2 需要的更多列,因此我执行以下操作将其插入新的临时表,然后将我需要的列复制到 Table1:
my_dataframe.to_sql("tmp", conn, if_exists="replace", index=False)
cur.execute("INSERT INTO Table1 (col1, col2) SELECT col1, col2 FROM Table2")
问题是,在循环的第二次迭代中,当 pandas 尝试删除 tmp 表时出现错误。完整代码如下:
def get_data(api_id, conn):
my_dataframe = call_to_api(api_id)
my_dataframe.to_sql("tmp", conn, if_exists="replace", index=False)
cur.execute("INSERT INTO Table1 (col1, col2) SELECT col1, col2 FROM Table2")
for chunk in pd.read_sql_query("SELECT id_for_api FROM Table1", conn, chunksize=10):
ids = chunk["id_for_api"].values
for api_id in ids:
get_data(api_id, conn)
我得到的错误是:
DatabaseError: Execution failed on sql 'DROP TABLE "tmp"': database table is locked
这是由这一行提出的:
pd.DataFrame(data).to_sql("tmp", conn, if_exists="replace", index=False)
我已经尝试了我能想到的一切来解决这个问题:
- 将连接更改为isolation_level=None(自动提交)
- 在
INSERT语句后添加conn.commit() - 在
get_data函数 (cur = conn.cursor()) 中创建新光标 - 使用
read_sql_query(conn2 = sqlite3.connect('mydb.db')) 创建一个新连接以用于外部循环
我错过了什么?关于 sqlite 隔离级别或锁定有什么我不明白的地方吗?
【问题讨论】:
-
有没有想过这个问题?进入我的第二天试图让这个工作。
-
@jseals,很遗憾没有。我作为一种解决方法所做的只是从第一个表中查询我需要的所有行(而不是在循环中),将它们放入 Python 列表中,然后使用该 Python 列表来构造我对第二个表的查询。这并不理想,但我必须继续前进,这对我的项目很有效。
标签: python pandas database sqlite