Python3导入Excel至SQLite时如何正确设置列字段类型
问题根因
你碰到的ID列带.0后缀、被识别为REAL类型的问题,根本不是操作错误,是两个环节的默认逻辑自动导致的:
- 读Excel阶段的类型偏差:pandas读Excel时,只要某一列有哪怕1个空单元格,整列的整数类型就会被自动转成float64——原因是pandas的普通整数类型没法存空值,只能靠带小数的浮点类型承载NaN空值。
- 写库阶段的类型映射规则:pandas默认会把float64类型映射成SQLite的REAL类型,最后就出现了1.0、2.0这种带小数后缀的效果。
另外提一句,你贴的原代码有个小语法错误:wb.[sheet] 是非法写法,正确是 wb[sheet],不然代码根本跑不起来。
自定义字段类型的实现方法
完全不用等数据写完再用sqlitebrowser手动改表结构,直接用to_sql方法自带的dtype参数,在写入的时候就把每个列的目标字段类型指定好就行,非常方便。
操作方法
- 对照业务需求,提前整理好每个列要对应什么SQLite字段类型
- 遍历所有工作表写入数据库时,把整理好的类型映射传给
dtype参数,强制指定字段类型
可直接运行的参考代码
import sqlite3 import pandas as pd con = sqlite3.connect("test.db") # sheet_name=None 会读入文件里所有工作表,返回{工作表名: 对应数据框}的字典 wb = pd.read_excel("for_DB_data.xlsx", sheet_name=None) for sheet_name, df in wb.items(): # 按照你的实际表结构修改类型映射,没列在里面的字段会走pandas默认推断 type_map = { "ID": "INTEGER", # 举个其他列的配置例子 "年龄": "INTEGER", "联系电话": "TEXT" } # 写库的时候传入类型映射 df.to_sql( name=sheet_name, con=con, if_exists="replace", index=False, dtype=type_map ) con.commit() con.close()
实用注意点
- 上面的代码直接用字符串写SQLite字段类型,不需要额外装sqlalchemy之类的依赖,你现在能跑通现有代码的环境直接就能用。
- 只要给ID列指定了INTEGER类型,原来的浮点形式的整数值(比如1.0、2.0)会自动转成无后缀的整数写入,空值会存为SQLite标准的NULL,不会再出现.0后缀的问题。
- 如果想少写重复的映射代码,也可以在读Excel的时候就把需要存整数的列强制转成pandas的可空整数类型
Int64,后续写库的时候pandas会自动把这个类型映射成SQLite的INTEGER,不需要再单独传dtype参数:# 读文件时直接指定列的pandas内部类型 wb = pd.read_excel( "for_DB_data.xlsx", sheet_name=None, dtype={"ID": "Int64", "年龄": "Int64"} )
内容的提问来源于stack exchange,提问作者2e6d7c49e26c
相关产品推荐
相关产品推荐

