【问题标题】:django db migration failed with postgresdjango db 迁移因 postgres 而失败
【发布时间】:2016-01-01 18:59:59
【问题描述】:

我对模型进行了一些更改,然后运行了一个

python manage.py makemigrations python manage.py 迁移

我得到了这个回溯:

Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: sessions, admin, study, auth, quiz, contenttypes, main
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying quiz.0013_auto_20151005_0644...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 393, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 444, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 222, in handle
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 110, in migrate
    self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 154, in apply_migration
    self.recorder.record_applied(migration.app_label, migration.name)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/recorder.py", line 67, in record_applied
    self.migration_qs.create(app=app, name=name)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 348, in create
    obj.save(force_insert=True, using=self.db)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 734, in save
    force_update=force_update, update_fields=update_fields)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 762, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 846, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 885, in _do_insert
    using=using, raw=raw)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 920, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 974, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 97, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: duplicate key value violates unique constraint "django_migrations_pkey"
DETAIL:  Key (id)=(27) already exists.

我不知道如何解释主键已经存在的错误。奇怪的是,它将字段添加到数据库中,因为我看到它在我的站点上输出,当我运行 shell 时,我可以看到字段已添加,并且填充了“我选择的”默认数据。

我决定再次运行迁移,看看它是否会在第二次后通过,我得到了不同的回溯...

   Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: sessions, admin, study, auth, quiz, contenttypes, main
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying quiz.0013_auto_20151005_0644...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 393, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 444, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 222, in handle
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 110, in migrate
    self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 148, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/migration.py", line 115, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/operations/fields.py", line 62, in database_forwards
    field,
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/schema.py", line 398, in add_field
    self.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/schema.py", line 111, in execute
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 97, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: column "lang1_back_to_choice" of relation "quiz_langpairinstructions" already exists

现在,如果我再试一次,我总会得到第二次回溯。我想知道我应该怎么做才能在未来进行迁移。如果数据库本身似乎一切顺利,为什么我会收到此错误?

【问题讨论】:

    标签: django postgresql


    【解决方案1】:

    我忽略了“django_migrations_pkey”列的名称,但我没有意识到它在数据库中。不知何故,django 比实际数据库落后了一步,并试图使用主键 (pk=27) 而不是它实际所在的数字(应该是 28)

    我不确定如何从 django 中更改它,所以我只是从数据库中删除了最后一列,因此它是一个更短的主键,并且与 django 一致,它开始工作得很好。

    【讨论】:

    • 你能不能也加上你用来删除最后一列的命令以及应该删除什么表。这可以使您的答案对像我这样的领域的新开发人员非常有用。
    【解决方案2】:

    还有另一种方法。既然您知道django_migrations 表中的最后一个id 值,就说它是100。那么,您需要这样做:

    ALTER SEQUENCE django_migrations_id_seq RESTART WITH 101;
    

    【讨论】:

      【解决方案3】:

      在我之前手动修改了 django 迁移表条目后出现了这个错误(在添加了一些以前不可靠的迁移然后删除之后)。

      这使得 django_migrations IDs 乱序(可以这么说)与 django_migrations 表中条目的默认位置。

      问题是 django 使用最后一个条目的 ID 和 +1 来创建一个新条目(在下表中:197 + 1 = 198),但是您可以看到 Key (id)=(198) 已经存在在表中。

      187 | foo_app             | 0016_auto_20161220_2332                     | 2017-01-06 05:22:07.666172+00
      198 | bar_app             | 0004_auto_20160423_2122                     | 2017-01-13 05:38:31.922738+00
      197 | baz_app             | 0013_auto_20170203_2311                     | 2017-02-08 18:50:22.70143+00
      

      如您所见,左侧主键的数字是乱序的。 我所做的是手动删除 django_migration 中的乱序条目,然后重新添加它们。

      DELETE from django_migrations where name = '0004_auto_20160423_2122';
      DELETE from django_migrations where name = '0013_auto_20170203_2311';
      
      INSERT INTO django_migrations VALUES (188, 'baz_app', '0013_auto_20170203_2311', date());
      INSERT INTO django_migrations VALUES (189, 'bar_app', '0004_auto_20160423_2122', date());
      

      另外值得注意的是,我最初尝试添加'new_app,'0002_auto_00000000_1111'的迁移实际上修改了postgres中的new_app表,但是django_migrations表没有得到更新。

      所以我第二次尝试重新运行迁移 0002_auto_00000000_1111 我得到了错误:

      django.db.utils.ProgrammingError: column "new_app_field" of relation "new_app_new" already exists
      

      我上面的解决方案为我解决了这个问题。

      【讨论】:

        【解决方案4】:

        简单地重新索引 django_migrations 表对我有用。

        在终端中执行这些步骤

        将用户更改为root

        $ sudo su
        

        这样您就可以将用户更改为 postgres

        $ su postgres
        

        选择你的数据库打开 postgres 终端客户端

        $ psql name_of_your_db
        

        在 postgres 客户端发出以下命令

        REINDEX TABLE django_migrations;
        

        然后退出postgres客户端

        \q
        

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-14
        • 2012-02-24
        • 1970-01-01
        • 2016-07-19
        • 1970-01-01
        • 2020-05-29
        相关资源
        最近更新 更多