ChatGPT解决这个技术问题 Extra ChatGPT

如何简化 Django 1.7 中的迁移?

South 已经有类似的问题,但我已经使用 Django 1.7 开始了我的项目,并且没有使用 South。

在开发过程中,已经创建了很多迁移,但是该软件尚未交付,并且不存在必须迁移的数据库。因此,我想重置迁移,就好像我当前的模型是原始模型一样,并重新创建所有数据库。

推荐的方法是什么?

编辑:从 Django 1.8 开始,有一个名为 squashmigrations 的新命令或多或少地解决了这里描述的问题。

重置迁移意味着什么?撤消吗?

A
Aristide

我懂了。我刚刚想通了,这很好。

首先,清除迁移表: ./manage.py migrate --fake zero

删除 app-name/migrations/ 文件夹或内容。

进行迁移: ./manage.py makemigrations

最后在不进行其他数据库更改的情况下整理您的迁移:./manage.py migrate --fake


这是一个很好的答案。仅删除迁移并不能消除错误迁移造成的任何损害。这实际上清理了石板并让您重新开始。
如果您详细说明一下,这应该是公认的答案。
伟大的单行答案兄弟,我不知道这是做什么的
这一行简单地逐一反转迁移,直到 zero。对于 Django 迁移系统,<app-name> 现在是一个新应用程序,makemigrations <app-name> 将从 0001 开始。 --fake 防止表被实际修改,迁移应该只标记为反向而不实际应用于架构。 (为了完整起见,添加了一些小解释,@tani-rokk,@Fabrizio)
manage.py migrate --fake <app-name> zero 清除迁移表,然后删除 <app-name>/migrations/ 文件夹或内容。然后是 manage.py makemigrations <app-name>,最后是 manage.py migrate --fake <app-name>。这将整理您的迁移,而无需进行其他数据库更改。
t
tijs

在 Django 1.7 版本的迁移中,过去在 South 中的重置功能已被删除,取而代之的是用于“压缩”迁移的新功能。这应该是控制迁移数量的好方法。

https://docs.djangoproject.com/en/dev/topics/migrations/#squashing-migrations

如果您仍然想真正从头开始,我假设您仍然可以通过清空迁移表并删除迁移,然后再次运行 makemigrations


除了清空迁移表之外,我将如何“删除迁移”?我会删除整个文件夹还是只删除 00X_*.py 文件?
使用 South 您可以删除迁移文件夹,当您再次运行 makemigrations 时将重新创建该文件夹。我认为这对 Django 1.7 是一样的
只是一个注释。在 Django 1.7 中,如果您不小心删除了迁移文件夹,如果您的模型是另一个 raise KeyError("Migration %s dependencies reference nonexistent parent node %r" % (migration, parent)) 的子模型,它可能会引发异常
具体来说,./manage.py squashmigrations myapp 0004 将在您的应用程序 myapp 中迁移 0004 之前压缩所有迁移。这将创建一个单一的压缩迁移。
s
shalbafzadeh

我只是有同样的问题。这是我的解决方法。

#!/bin/sh
echo "Starting ..."

echo ">> Deleting old migrations"
find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
find . -path "*/migrations/*.pyc"  -delete


# Optional
echo ">> Deleting database"
find . -name "db.sqlite3" -delete

echo ">> Running manage.py makemigrations"
python manage.py makemigrations

echo ">> Running manage.py migrate"
python manage.py migrate

echo ">> Done"

find 命令:http://unixhelp.ed.ac.uk/CGI/man-cgi?find


这会删除数据,而不仅仅是迁移
你也应该删除 .pyc 文件
佚名

假设这是您的项目结构,

project_root/
    app1/
        migrations/
    app2/
        migrations/
    ...
    manage.py
    remove_migrations.py

您可以从上面指示的位置运行脚本 remove_migrations.py 以删除所有迁移文件。

#remove_migrations.py
"""
Run this file from a Django =1.7 project root. 
Removes all migration files from all apps in a project.
""" 
from unipath import Path

this_file = Path(__file__).absolute()
current_dir = this_file.parent
dir_list = current_dir.listdir()

for paths in dir_list:
    migration_folder = paths.child('migrations')
    if migration_folder.exists():
        list_files = migration_folder.listdir()
        for files in list_files:
            split = files.components()
            if split[-1] != Path('__init__.py'):
                files.remove()

如果您有一个复杂的项目,手动删除可能会很累。这为我节省了很多时间。删除迁移文件是安全的。我已经这样做了无数次而没有遇到任何问题……但是。

但是,当我删除迁移文件夹时,makemigrationsmigrate 并没有为我创建该文件夹。该脚本确保迁移文件夹及其 __init__.py 保持不变,仅删除迁移文件。


您可以删除迁移文件夹并使用空的 init.py 重新创建它们(例如 touch migrations/__init__.py
I
Ibrohim Ermatov

删除文件:delete_migrations.py(在 prj 的根目录中):

import os for root, dirs, files in os.walk(".", topdown=False): for name in files: if '/migrations' in root and name != '__init__.py': os.remove(os. path.join(根,名称))

DELETE FROM django_migrations where app in ('app1', 'app2'); ./manage.py makemigrations ./manage.py 迁移 --fake

或者,您可以从这一切编写迁移


我必须为 ./manage.py makemigrations 指定应用程序名称才能工作,如下所示:./manage.py makemigrations orders alerts
c
chirale

我尝试了不同的命令,其中一些答案对我有帮助。在我的例子中,只有这个序列修复了 MYAPP 中迁移中损坏的依赖关系,并从头开始清理所有过去的迁移。

在执行此操作之前,请确保数据库已经同步(例如,不要在此处添加新的模型字段或更改元选项)。

rm -Rf MYAPP/migrations/*
python manage.py makemigrations --empty MYAPP
python manage.py makemigrations
python manage.py migrate --fake MYAPP 0002

其中 0002 是最后一个 makemigrations 命令返回的迁移编号。

现在您可以再次正常运行 makemigrations / migrate 因为迁移 0002 已存储但未反映在已同步的数据库中。


在上面提到的所有解决方案中,只有这对我有用,没有故障,也没有删除数据库。
v
vokimon

如果您不关心以前的迁移,那么仅删除 migrations/ 目录中的所有迁移怎么样?您将从头开始迁移序列,以您当前的模型作为参考,就好像您现在已经编写了整个模型一样。

如果您不相信我可以删除,请尝试将它们移走。


保留旧迁移有什么意义?当有人尝试从 django 1.6 升级到 1.8 时,我的问题就迎刃而解了。
迁移只是您对数据库所做更改的跟踪记录。当我的迁移链停止工作时,我不止一次听取了 vokiman 的建议。
s
sprksh

一个简单的方法是

转到每个应用程序并删除迁移文件。

然后转到数据库中的 django-migrtaions 表并截断它(删除所有条目)。

之后,您可以再次创建迁移。


删除迁移文件时,请确保不要删除 init 文件。
这真的帮助了我。我删除了所有迁移,从我的 sqlite DB 中删除了表,但仍然无法进行迁移......但是,一旦我恢复了 _init_.py 文件(doh),我就能够再次进行迁移并开始巡航。 @sprksh = 救生员!
v
vabada

cd 到 src 目录 cd /path/to/src

删除迁移目录 rm -rf your_app/migrations/

请注意,这应该分别为每个应用程序完成

迁移python3.3 manage.py migrate

如果您想重新开始python3.3 manage.py makemigrations your_app


m
mrmuggles

如果您处于开发模式并且只想重置所有内容(数据库、迁移等),我会根据 Abdelhamid Ba 的回答使用此脚本。这将擦除数据库(Postgres)的表,删除所有迁移文件,重新运行迁移并加载我的初始固定装置:

#!/usr/bin/env bash
echo "This will wipe out the database, delete migration files, make and apply migrations and load the intial fixtures."

while true; do
    read -p "Do you wish to continue?" yn
    case $yn in
        [Yy]* ) make install; break;;
        [Nn]* ) exit;;
        * ) echo "Please answer yes or no.";;
    esac
done

echo ">> Deleting old migrations"
find ../../src -path "*/migrations/*.py" -not -name "__init__.py" -delete

# Optional
echo ">> Deleting database"
psql -U db_user -d db_name -a -f ./reset-db.sql

echo ">> Running manage.py makemigrations and migrate"
./migrations.sh

echo ">> Loading initial fixtures"
./load_initial_fixtures.sh

echo ">> Done"

重置-db.sql 文件:

DO $$ DECLARE
    r RECORD;
BEGIN
    -- if the schema you operate on is not "current", you will want to
    -- replace current_schema() in query with 'schematodeletetablesfrom'
    -- *and* update the generate 'DROP...' accordingly.
    FOR r IN (SELECT tablename FROM pg_tables WHERE schemaname = current_schema()) LOOP
        EXECUTE 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
    END LOOP;
END $$;

迁移.sh 文件:

#!/usr/bin/env bash
cd ../../src
./manage.py makemigrations
./manage.py migrate

load_initial_fixtures.sh 文件:

#!/usr/bin/env bash
cd ../../src
./manage.py loaddata ~/path-to-fixture/fixture.json

请务必将路径更改为与您的应用程序相对应。我个人将这些脚本放在一个名为 project_root/script/local 的文件夹中,而 django 的源代码在 project_root/src 中。


s
shacker

在我的应用程序中(手动)删除每个“迁移”文件夹后,我运行:

./manage.py dbshell
delete from django_migrations;

然后我想我可以做./manage.py makemigrations来重新生成它们。但是,没有检测到任何变化。然后我尝试一次指定一个应用程序:./manage.py makemigrations foo./manage.py makemigrations bar。但是,这导致无法解决的循环依赖关系。

最后,我运行了一个 makemigrations 命令,该命令指定了我的所有应用程序(无特定顺序):

./manage.py makemigrations foo bar bike orange banana etc

这一次,它起作用了——循环依赖被自动解决(它在必要时创建了额外的迁移文件)。

然后我能够运行 ./manage.py migrate --fake 并重新开始工作。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅