Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django是否提供任何内置方式来更新PostgreSQL自动增量计数器?_Python_Django_Postgresql - Fatal编程技术网

Python Django是否提供任何内置方式来更新PostgreSQL自动增量计数器?

Python Django是否提供任何内置方式来更新PostgreSQL自动增量计数器?,python,django,postgresql,Python,Django,Postgresql,我正在将Django站点从MySQL迁移到PostgreSQL。数据量不是很大,所以我采取了一种非常简单的方法:我只是使用内置的Django例程创建JSON记录,然后将它们加载到新实例中,循环对象,并将每个对象保存到新数据库中 这很好地工作,但有一个小问题:加载所有记录后,在加载旧记录后尝试添加新数据时,我遇到了一个IntegrityError。与MySQL自动增量ID字段等效的Postgres是一个串行字段,但是当显式指定ID值时,串行字段的内部计数器不会增加。结果,Postgres尝试从1开

我正在将Django站点从MySQL迁移到PostgreSQL。数据量不是很大,所以我采取了一种非常简单的方法:我只是使用内置的Django例程创建JSON记录,然后将它们加载到新实例中,循环对象,并将每个对象保存到新数据库中

这很好地工作,但有一个小问题:加载所有记录后,在加载旧记录后尝试添加新数据时,我遇到了一个
IntegrityError
。与MySQL自动增量ID字段等效的Postgres是一个串行字段,但是当显式指定ID值时,串行字段的内部计数器不会增加。结果,Postgres尝试从1开始对记录进行编号(已使用),从而导致违反约束。(这是Django的已知问题,标记为。)

有相当多的问题和答案与此相关,但似乎没有一个答案能够直接在Django的背景下解决这个问题。给出了更新计数器需要运行的查询的示例,但我尽量避免在可能的情况下进行显式查询。我可以在保存之前简单地删除ID字段,并让Postgres自己进行编号,但是在这种情况下,
ForeignKey
引用将被破坏。其他一切都很完美

如果Django提供了一个能够智能地处理任何边缘情况的例程,那就太好了。(这不会修复这个bug,但它会允许开发人员以一致和正确的方式解决它。)我们真的需要使用原始查询来修复这个问题吗?这看起来太野蛮了

如果真的没有这样的例程,我只需要做下面的事情,直接运行上面链接的答案中建议的查询。但在这种情况下,我很想听听这种方法的任何潜在问题,或者关于我可能做错了什么的任何其他信息。例如,我是否应该修改记录以使用UUID,如图所示

以下是原始方法(经过编辑以反映我实际完成的工作的简化版本)。这与他的答案非常接近,但我觉得他的答案更有力

table = model._meta.db_table
cur = connection.cursor()
cur.execute(
    "SELECT setval('{}_id_seq', (SELECT max(id) FROM {}))".format(table, table)
)
一个选项是在序列化和反序列化期间使用。这样,当您将它插入到PostgreSQL中时,它将自动增加主键字段并使所有内容保持内联


这种方法的缺点是,每个模型都需要一组不包含id的唯一字段。

关于争论:我的案例是一次性迁移,我的决定是在完成每个表的迁移后立即运行此函数,尽管您可以在怀疑完整性可能被破坏时随时调用它

    def synchronize_last_sequence(model):
        #  Postgresql aut-increments (called sequences) don't update the 'last_id' value if you manually specify an ID.
        #  This sets the last incremented number to the last id
        sequence_name = model._meta.db_table+"_"+model._meta.pk.name+"_seq"
        with connections['default'].cursor() as cursor:
            cursor.execute(
                "SELECT setval('" + sequence_name + "', (SELECT max(" + model._meta.pk.name + ") FROM " +
                model._meta.db_table + "))"
            )
        print("Last auto-incremental number for sequence "+sequence_name+" synchronized.")
我使用了您在问题中提出的SQL查询。 找到你的帖子非常有用。谢谢大家!


它应该适用于自定义PKs,但不适用于多字段PKs。

您打算进行多少次此转换,是否计划再次转换回MySQL?如果它接近1且为否,那么为什么要尝试将其自动化?只需直接在查询工具中运行查询,在导入过程中关闭fkey检查,以及本书中的任何其他肮脏技巧,然后再次打开所有内容并使其美观。(附言:原始sql不是野蛮的,它是有用的:-)@thebjorn,啊,公平点。理论上,在这种情况下,它接近1,但我预计必须为几个不同的项目执行它,所以我希望能够编写一个标准化的导出/导入脚本来处理这个怪癖。(对不起——“野蛮”可能不公平。)我非常喜欢这种方法。再多做一点工作,但是很自然!我会等一等,看看别人怎么说。