Dockerized Django应用未应用唯一约束

时间:2019-06-20 08:04:07

标签: python django postgresql docker pgadmin-4

我有两个相互关联的问题

问题#1

我的应用程序具有一个在线Postgres数据库,该数据库用于存储数据。因为这是一个Dockerized应用程序,所以我创建的迁移不再出现在本地主机上,而是存储在Docker容器中。 到目前为止,我所看到的所有问题似乎在迁移和向表中的字段之一添加唯一约束方面都没有问题。

我编写了shell代码来运行python脚本,该脚本在命令提示符窗口中向我返回了迁移文件的内容。我能够获得将要应用的迁移文件,并在django_migrations表中添加了一行以指定相同的文件。然后我运行了makemigrations并进行了迁移,但是它说没有应用更改(这使我相信,我添加到数据库中的行应该仅在django自行检测到迁移后才由django自动创建,而不是由我指定迁移文件并要求其进行更改)。问题在于,现在,新迁移仍会检测到以下更改

Migrations for 'mdp':
  db4mdp/mdp/migrations/0012_testing.py
    - Alter field mdp_name on languages

尽管检测到此明显的“变化”,但出现以下错误,

return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "mdp_mdp_mdp_fullname_281e4228_uniq" already exists

我已经使用pgadmin4在postgres服务器上进行了检查,以检查约束是否已实际应用到它。并且具有上面指定的关系旁边的名称。那么为什么Django显然将其检测为要进行的更改呢?关键是,如果我现在删除在python目录中创建的新迁移文件,它可能会运行(因为更改已在数据库中“显然”进行了),但我没有跟踪迁移的文件的变化。尽管现在我使用的是在线数据库,但是我不需要保留迁移。我不会回滚所做的任何更改,也不会经常进行更改。这只是一两次的事情,但我想解决错误。

问题2

我在上述问题中使用“明显”的原因是,即使我的公共模式中的约束部分显示出由于某些原因,当我尝试使用以下命令在表中创建新条目时,约束已被应用我定义为唯一的字段中的非唯一字符串,无论如何它允许创建它。

2 个答案:

答案 0 :(得分:1)

您永远不会手动将任何内容添加到django_migrations表。让django去做。如果未执行此操作,则无论如何,您的代码尚不适合生产。 我了解您正在docker内部进行开发。完成后,将docker卷挂载到本地卷。由于尚未安装,因此您的migratins不会在本地显示。 请参阅Volumes。它应该可以解决您的问题。

答案 1 :(得分:0)

对于任何由于时间限制而试图尝试解决此问题(而不是装入卷)的人,此答案可能会有所帮助,但是@deosha仍然是解决此问题的正确方法。我通过删除所有表和与迁移到我的特定应用程序相对应的行来解决此问题(不必删除auth表等,因为您将不会删除与django_migrations表中的行相对应的行)。之后,我在Dockerfile调用的shell脚本中使用了以下内容。

python manage.py makemigrations --name testing
python testing_migrations.py

它需要为下一步命名。在这行代码之后,我运行了包含以下代码的python脚本testing_migrations:

import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
migrations_file = os.path.join(BASE_DIR, '<path_to_new_migration_file>')
with open(migrations_file, 'r') as file:
    print(file.read())

通常,为您创建的应用创建的第一个迁移将是/0001_testing.py(这就是为什么需要更早命名的原因)。由于该文件的内容在容器启动和运行时对容器可见,因此您将能够打印该文件的内容。然后运行migration命令。这将在django_migrations表中创建一列,使django似乎已应用了迁移。但是,在您的本地计算机上,此迁移文件不存在。因此,请从上面的打印语句中复制文件的内容,并将其放入与上述名称相同的.py文件中,并将其保存在本地设备上的上述迁移文件夹中。

对于所有连续的迁移,您都可以按照此方法进行操作,方法是重复此过程,并根据需要增加test_migrations文件中的数字。

完成表格压缩后的迁移将有所帮助。如果您正在开发中,并且不需要回滚对数据库模式的更改,则只需删除所有迁移文件以及django_migrations表中与您的应用相对应的行,然后将其投入生产即可,就像最初所做的那样。 。放下表格,让您的第一个新迁移文件重新创建它们,然后再次导入数据。

这不是推荐的方法。如果您不紧缩时间,请使用deosha。