我有一个postgres表,用于保存用户文件。两个用户可以拥有一个具有相同名称的文件,但不允许用户拥有两个具有相同名称的文件。目前,如果用户尝试上传具有已使用名称的文件,则数据库将按原样吐出错误。
IntegrityError:重复键值违反了唯一约束" file_user_id_title_key"
我想要做的是首先使用文件名和用户ID查询数据库,以查看用户是否正在使用文件名。如果名称已被使用,则返回错误,否则写入行。
cur.execute('INSERT INTO files(user_id, title, share)'
'VALUES (%s, %s, %s) RETURNING id;',
(user.id, file.title, file.share))
答案 0 :(得分:0)
问题是如果不打开竞争条件就不能真正做到这一点:
没有什么可以阻止其他人在您查询表和尝试插入行之间插入冲突行,因此错误仍然可能发生(除非您采取极端措施,例如在执行此操作之前锁定表,这会严重影响并发性。)
此外,您提出的技术会通过添加多余的第二个查询来增加数据库的负载。
你是对的,你不应该用数据库错误消息对付用户,但正确的处理方法如下:
INSERT
就像您展示的新行一样。unique_violation
),您知道用户已经有这样的文件并向用户显示相应的错误。因此,您可以将INSERT
语句视为原子操作检查是否已有匹配的条目,如果没有,则添加行。