SQLAlchemy因为DBSession.add()操作导致IntegrityError错误

6
在这个脚本中第二个时间线调用了121,http://paste.pocoo.org/show/520040/,我收到了以下错误信息:
*** IntegrityError: (IntegrityError) duplicate key value violates unique constraint "heroes_pkey"
DETAIL:  Key (id)=(14) already exists.
 'INSERT INTO heroes (id, name, description, image_name, default_filename, faction, stat, roles, strength, agility, intelligence, strength_gain, agility_gain, intelligence_gain, min_hp, max_hp, min_mana, max_mana, min_damage, max_damage, armor, movespeed, attack_range, min_attack_animation, max_attack_animation, min_cast_animation, max_cast_animation, base_attack_time, missile_speed, day_site_range, night_site_range, resource_name, "order") VALUES (%(id)s, %(name)s, %(description)s, %(image_name)s, %(default_filename)s, %(faction)s, %(stat)s, %(roles)s, %(strength)s, %(agility)s, %(intelligence)s, %(strength_gain)s, %(agility_gain)s, %(intelligence_gain)s, %(min_hp)s, %(max_hp)s, %(min_mana)s, %(max_mana)s, %(min_damage)s, %(max_damage)s, %(armor)s, %(movespeed)s, %(attack_range)s, %(min_attack_animation)s, %(max_attack_animation)s, %(min_cast_animation)s, %(max_cast_animation)s, %(base_attack_time)s, %(missile_speed)s, %(day_site_range)s, %(night_site_range)s, %(resource_name)s, %(order)s)' {'day_site_range': 1800, 'min_damage': 47, 'intelligence': 18.0, 'agility': 14.0, 'night_site_range': 800, 'min_attack_animation': 0.4, 'id': 66666, 'attack_range': 128, 'default_filename': None, 'strength_gain': 2.7, 'strength': 21.0, 'min_hp': 549, 'armor': 1.96, 'intelligence_gain': 1.5, 'movespeed': 300, 'max_hp': 1765, 'max_cast_animation': 0.51, 'stat': 'Strength', 'resource_name': None, 'description': None, 'faction': 'Radiant', 'missile_speed': 0, 'image_name': None, 'max_damage': None, 'min_cast_animation': 0.4, 'max_mana': 702, 'name': None, 'roles': 'Carry / Pusher', 'base_attack_time': 1.7, 'agility_gain': 1.3, 'min_mana': 234, 'max_attack_animation': 0.3, 'order': 4}

我知道我最有可能出现错误的原因是,因为前面的session.add()尝试向数据库添加一个已经存在主键的记录。但我不明白的是,通常情况下,在使用Postgresql时会自动发生这种情况,那么为什么在add()操作时自动增量的情况不会发生呢?值得注意的是,在错误消息中的这个部分“(id)=(14)”中的数字每次成功调用脚本时都会递增一。

1个回答

14

问题最终出在Postgres方面。我通过导入SQL文件创建了数据库,负责跟踪英雄主键的序列最终不准确了。这就解释了为什么id在每次运行后都会递增1,因为Postgres试图找到一个未被使用的主键。我通过在我的数据库上发出以下查询来解决它。

SELECT setval('heroes_id_seq', MAX(id)) FROM heroes;

它也帮助了我。但是为什么在删除最后一行(id为6)后,保留max(id) = 5,再次添加时却创建了id=7的行呢? 但是如果在添加之前运行这个命令,它会创建一个id=6的新行。 我需要在add()新行之前自动执行这行代码吗? 为什么Postgre不自己执行这个操作呢? - Anton Makarov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接