含列表类型列的pandas DataFrame写入SQLite数据库问题
问题解决方案
1. 报错根因与写入修复
报错确实由list_of_movies列的Python列表类型导致:SQLite原生不支持列表类型的存储,pandas.to_sql在做参数绑定时无法识别列表对象,直接抛出类型不支持的错误。
修复注意点:
- 写入数据库前,先将列表列转换为逗号分隔的字符串,逻辑和你之前计算最大长度的代码一致
- 移除原列表列,避免表字段不匹配
- 原建表语句存在语法错误,最后一个字段定义后缺少闭合右括号
- 如果调用
to_sql时传入if_exists='replace',pandas会自动删除已存在的同名表、按DataFrame字段类型重建表,你之前手动执行的CREATE TABLE语句会被完全覆盖,属于无效操作。如果要自定义表结构,需要将if_exists改为append。
列预处理代码示例:
# 将列表转为拼接字符串,对应数据库的movie_links字段 actor_dataframe['movie_links'] = actor_dataframe['list_of_movies'].apply(lambda x: ','.join(x)) # 删除原列表列 actor_dataframe = actor_dataframe.drop(columns=['list_of_movies'])
后续从数据库读取数据时,只需要对movie_links字段执行.split(',')即可还原为原始列表格式。
2. 动态传入字段长度参数
SQL语句无法直接解析Python变量,通过f-string做字符串拼接即可将longest_row的数值动态插入建表语句,修正后的完整函数如下:
def _actors_to_db(actor_dataframe, longest_row): # 预处理列表列 actor_dataframe['movie_links'] = actor_dataframe['list_of_movies'].apply(lambda x: ','.join(x)) actor_dataframe = actor_dataframe.drop(columns=['list_of_movies']) con = sqlite3.connect("example.db") cur = con.cursor() # f-string插入长度参数,补全建表语句的闭合括号 cur.execute(f""" CREATE TABLE IF NOT EXISTS actors (`name` varchar(255), `actor_link` varchar(255), `movie_links` varchar({longest_row})) """) con.commit() # 用append模式,避免覆盖自定义表结构 actor_dataframe.to_sql('actors', con, if_exists='append', index=False) con.commit() con.close() print("Actors saved to db!")
补充说明:SQLite中varchar(N)的长度定义不会做强制校验,即便存入的字符串长度超过N也可以正常存储,你计算的max_length仅作为字段定义参考,不会影响实际写入逻辑。
内容的提问来源于stack exchange,提问作者PetrSevcik
相关产品推荐
相关产品推荐

