Python中指定主键后使用Peewee ORM插入数据失败的问题求助
解决Peewee设置code为主键后无法插入数据的问题
先定位错误原因
你的异常捕获太宽泛,只打印"aa"根本看不到具体错误。先修改代码,打印详细异常信息,才能精准定位问题:
for data in corp_list._stock_codes: idx = corp_list._stock_codes.get(data) info = corp_list[idx].info stock = Stock( name=info.get("corp_name"), code=info.get("stock_code"), sector=info.get("sector"), product=info.get("product"), corp_code=info.get("corp_code"), corp_cls=info.get("corp_cls"), ) try: stock.save() except Exception as e: print(f"插入失败: {str(e)}, 对应数据: {info}")
常见问题及解决方法
1. stock_code为空或None
主键字段不允许为NULL,如果info.get("stock_code")返回空值,插入会直接失败。解决方法:插入前过滤掉无stock_code的数据:
for data in corp_list._stock_codes: idx = corp_list._stock_codes.get(data) info = corp_list[idx].info stock_code = info.get("stock_code") # 过滤空的stock_code if not stock_code: print(f"缺少股票代码,跳过数据: {info}") continue stock = Stock( name=info.get("corp_name"), code=stock_code, sector=info.get("sector"), product=info.get("product"), corp_code=info.get("corp_code"), corp_cls=info.get("corp_cls"), ) try: stock.save() except Exception as e: print(f"插入失败: {str(e)}, 对应数据: {info}")
2. 数据库中已存在相同code的记录
主键必须唯一,如果重复插入相同code的数据,会触发唯一约束错误。可以用两种方式处理:
方式一:用get_or_create(存在则获取,不存在则插入)
for data in corp_list._stock_codes: idx = corp_list._stock_codes.get(data) info = corp_list[idx].info stock_code = info.get("stock_code") if not stock_code: print(f"缺少股票代码,跳过数据: {info}") continue # 尝试获取或创建,defaults里是除主键外的字段 stock, created = Stock.get_or_create( code=stock_code, defaults={ "name": info.get("corp_name"), "sector": info.get("sector"), "product": info.get("product"), "corp_code": info.get("corp_code"), "corp_cls": info.get("corp_cls"), } ) # 如果记录已存在,可选择更新字段 if not created: stock.name = info.get("corp_name") stock.sector = info.get("sector") stock.product = info.get("product") stock.corp_code = info.get("corp_code") stock.corp_cls = info.get("corp_cls") stock.save()
方式二:用PostgreSQL的Upsert(效率更高)
因为你用的是PostgreSQL,Peewee支持直接用on_conflict实现更新插入:
for data in corp_list._stock_codes: idx = corp_list._stock_codes.get(data) info = corp_list[idx].info stock_code = info.get("stock_code") if not stock_code: print(f"缺少股票代码,跳过数据: {info}") continue # 插入或更新 Stock.insert( name=info.get("corp_name"), code=stock_code, sector=info.get("sector"), product=info.get("product"), corp_code=info.get("corp_code"), corp_cls=info.get("corp_cls"), ).on_conflict( conflict_target=[Stock.code], # 冲突字段是主键code # 冲突时更新这些字段 preserve=[Stock.name, Stock.sector, Stock.product, Stock.corp_code, Stock.corp_cls] ).execute()
3. 数据库表结构未更新
修改模型(把code设为主键)后,如果没有重新生成表结构,原来的表可能还保留自动生成的id主键,或者code字段不是主键,导致插入失败。测试环境下可以直接重建表(注意:会清空原有数据):
# 先删除旧表 pg_db.drop_tables([Stock]) # 创建新表 pg_db.create_tables([Stock])
生产环境建议用peewee-migrate迁移工具修改表结构,避免数据丢失。
内容的提问来源于stack exchange,提问作者Eno _
相关产品推荐
相关产品推荐

