Python sqlite3设置dateandtime为主键后插入数据报no such column错误
错误根因
- 你在INSERT语句中完全混淆了SQL解析域和Python变量域的边界。SQLite收到你传入的SQL字符串后,只会把字符串中没有被引号包裹的标识符识别为数据库内的列名,完全不会感知到这些字符串是你Python代码里的变量名。因此SQLite会尝试查询
dateandtime、up_GDPgrowthRate等列的值来完成插入,但你的表中根本不存在up_开头的列,最先触发的报错就是no such column: dateandtime。 - 你对
INSERT INTO ... VALUES的语法使用错误。省略列名的INSERT写法要求VALUES后必须传入与表列顺序、数量完全匹配的字面值,你当前传入的全是数据库不存在的标识符,完全不符合语法规则。
修复方案
- 采用参数化查询传递变量:不要把Python变量直接拼接到SQL字符串里,使用SQLite支持的
?占位符代替字面值位置,将变量值作为execute方法的第二个参数传入,既可以彻底解决语法解析错误,也能避免SQL注入风险。 - 显式指定插入列名:不要依赖省略列名的顺序匹配,在INSERT语句中明确列出所有要插入的列名,避免后续表结构调整时出现顺序错配问题。
- 匹配列名与变量顺序:建表时的列名没有
up_前缀,需要确保传入的变量顺序和SQL中列出的列名顺序一一对应。
修正后的可运行插入代码示例:
c.execute( """ INSERT INTO economicdata (dateandtime, GDPgrowthRate, GDP, GNP, GDPperCapita, GDPagriculture, GDPconstruction, GDPmanufacturing, GDPmining, GDPpublicadmin, GDPservices, GDPtransport, GDPtourism, UnemploymentRate, EmploymentRate, InflationRate, CPI, InterestRate, BalanceOfTrade, CurrentAccount, Imports, Exports, FDI, GovernmentSpending, GovernmentDebt, BusinessConfidence, Bankruptcies, CompetitiveRank, CorruptionRank, ConsumerConfidence, CorporateTaxRate, IncomeTaxRate) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, # 按上面列名的顺序传入对应Python变量值 (dateandtime, up_GDPgrowthRate, up_GDP, up_GNP, up_GDPperCapita, up_GDPagriculture, up_GDPconstruction, up_GDPmanufacturing, up_GDPmining, up_GDPpublicadmin, up_GDPservices, up_GDPtransport, up_GDPtourism, up_UnemploymentRate, up_EmploymentRate, up_InflationRate, up_CPI, up_InterestRate, up_BalanceOfTrade, up_CurrentAccount, up_Imports, up_Exports, up_FDI, up_GovernmentSpending, up_GovernmentDebt, up_BusinessConfidence, up_Bankruptcies, up_CompetitiveRank, up_CorruptionRank, up_ConsumerConfidence, up_CorporateTaxRate, up_IncomeTaxRate) )
自定义主键替换默认rowid的说明
- 你当前将TEXT类型的
dateandtime设为NOT NULL PRIMARY KEY,SQLite只会为这个字段添加唯一非空约束,并不会自动移除系统默认的rowid隐藏列。 - 如果你确实希望完全去掉默认
rowid、以dateandtime作为物理存储主键,需要在建表语句末尾添加WITHOUT ROWID关键字,示例:
注意:CREATE TABLE economicdata ( dateandtime text NOT NULL PRIMARY KEY, -- 其余列定义与你原有逻辑保持一致 IncomeTaxRate decimal NOT NULL ) WITHOUT ROWID;WITHOUT ROWID表要求必须存在至少一个非空的主键,你当前的表结构完全满足要求。
额外注意
- 你当前通过
open("Economic_Analyser.db")判断数据库是否存在的写法存在隐患:只要路径下存在同名文件(哪怕不是合法的SQLite数据库),open操作就会成功,不会触发建表分支,后续SQL连接时会抛出“不是有效数据库文件”的错误。更稳妥的方式是直接尝试执行sqlite连接,通过捕获OperationalError判断是否需要初始化表结构。
内容的提问来源于stack exchange,提问作者user15175153
相关产品推荐
相关产品推荐

