(重新)根据“备份”表说明创建表

时间:2019-03-22 13:27:23

标签: python django postgresql

问题

最近,我遇到了一个与客户有关的问题,该问题有很多解决方案,但都不容易。此应用程序使用Postgresql DB,并且有两种环境:devprod

在某些时候,有人认为从module_people_new中删除其中一个表(prod)是一个好主意,而不必考虑FK及其可能带来的其他问题。幸运的是,它是一个与应用程序耦合程度不高的模块,因此该应用程序可以正常运行。

当我开始使用该应用程序时,某些功能由于完整性错误而失败,因此我发现是因为这个原因。我在dev中尝试了相同的功能,发现它们正在工作,因此表格在那里。

PostgreSQL表说明

现在,我想知道是否有一种方法可以从我在prod中获得的信息中“恢复” dev中的该表。我知道我可以只获取表描述并从那里建立一个创建查询,但是我想知道是否还有一种更“直接”的方法。用表描述,我的意思是:

db-> \d+ module_people_new
                               Table "public.module_people_new"
          Column           |           Type           | Modifiers | Storage  | Stats target | Description
---------------------------+--------------------------+-----------+----------+--------------+-------------
 id                        | integer                  | not null  | plain    |              |
 created_at                | timestamp with time zone | not null  | plain    |              |
 updated_at                | timestamp with time zone | not null  | plain    |              |
 first_name                | character varying(255)   | not null  | extended |              |
 last_name                 | character varying(255)   | not null  | extended |              |
 user_id                   | integer                  | not null  | plain    |              |
 . . .
Indexes:
    "module_people_pkey" PRIMARY KEY, btree (id)
    . . .
Check constraints:
    . . .
Foreign-key constraints:
    "module_user_id_4d9d48da00e81837_fk_module_user_id" FOREIGN KEY (user_id) REFERENCES module_user(id) DEFERRABLE INITIALLY DEFERRED
    . . .

另一种可能性

该应用程序是Django应用程序,因此我也进行了迁移,但恐怕有一些更改可能会影响该表及其他相关内容。但是,也许我可以使用它。唯一的问题是,我不想复制粘贴迁移并只是简单地应用它,交叉手指并希望它能工作。我知道您可以从Django ORM查询中获取SQL查询,也许还有一种从迁移中获取查询的方法?

非常感谢:)

2 个答案:

答案 0 :(得分:2)

我想到的一种可能性是使用inspectdb检查dev中的表并将其输出到模型中。

python manage.py inspectdb module_people_new > models.py

然后生成迁移并在生产中创建表。然后,您可以创建一个脚本来重新填充表格,如下所示:

# some_script.py

from some_app.models import User

# assuming `module_people_new` table's Model Name is ModulePeople

for user in User.objects.all():
   ModulePeople.objects.get_or_create(user=user, first_name=user.first_name, ...)

然后使用该脚本,如下所示:

python manage.py shell < some_script.py

或者,如果您想直接从dev中填充数据库中的数据,则可以使用fixtures。您可以从开发者那里dumpdata,并在生产环境中使用loaddata

答案 1 :(得分:0)

基于@ruddra的回答,我最终这样做:

  1. 将模型人复制到新模型中。
  2. 删除related_names(此模型中有一些)并删除db_table(这就是表末尾有_new的原因)
  3. 生成迁移:python manage.py makemigrations
  4. 应用迁移:python manage.py migrate
  5. 将新模型表重命名为缺少的People表名(_id_seq表也是如此)
  6. 应用假迁移以返回到新模型迁移之前的状态:
python manage.py migrate --fake app_name 0XXX_..._...
  1. 删除新模型并进行迁移

就是这样!