繁体   English   中英

在生产系统中重置 Django 迁移

Resetting Django Migrations in a Production System

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

自从几年前我开始使用该框架以来,我已经阅读了很多涉及 Django Migrations 的帖子/文章/试错,所以我决定发布一个自我回答的问题,指出完成清理的正确方法在生产数据库中重置迁移,让您拥有与之前相同的数据库结构,但从初始迁移开始。

总的来说,问题是这样的

当你有一个更大的项目时,你开始为使用 Django 构建的系统积累大量的迁移。 这通常不是问题,但是当您开始累积超过 50-100 个迁移文件(其中很多是添加和删除相同字段)时,最好有一个“清理”选项,因为它应该是众所周知,如果您错误地更改了迁移历史记录,您将留下一个或多或少冻结在先前数据库状态的系统,其中解决问题的唯一方法是手动基于 sql 的迁移更改。

1 个回复

我为这个问题提出的解决方案分步骤:

步骤 1创建迁移以删除您想要的任何模型或字段并在本地运行它们,您的开发系统必须与所有其他开发人员系统以及生产系统同步……如果不是这种情况,您需要确保同步!

第 2 步

  1. 删除本地迁移文件(一个不错的选择是更改我下面的命令,我目前在名为/apps/的目录中有一个目录结构,其中包含我的系统的应用程序

运行调用python manage.py delete_local_migration_files (如果你这样命名)

import os

import django.apps
from django.conf import settings
from django.core.management.base import BaseCommand


def delete_migrations(app):
    print(f"Deleting {app}'s migration files")
    migrations_dir = os.path.join(settings.BASE_DIR, f'apps{os.path.sep}{app}{os.path.sep}migrations')

    if os.path.exists(migrations_dir):
        for the_file in os.listdir(migrations_dir):
            file_path = os.path.join(migrations_dir, the_file)
            try:
                if os.path.isfile(file_path):
                    os.unlink(file_path)
            except Exception as e:
                print(e)

            f = open(f"{os.path.join(migrations_dir, '__init__.py')}", "w")
            f.close()

    else:
        print('-' * 20, migrations_dir, 'does not exist')


class Command(BaseCommand):
    """
    Resets migrations and clears directories
    """
    help = 'reset migrations'

    def handle(self, *args, **options):
        set_of_apps = set()
        disregard = []

        # get all apps
        for model in django.apps.apps.get_models():
            if model._meta.app_label not in disregard:
                set_of_apps.add(model._meta.app_label)

        for app in set_of_apps:
            delete_migrations(app)

第 3 步

  1. 从数据库中删除迁移(您可以使用下面的命令,它应该适用于任何使用 Postgres 的设置,但您必须根据需要更新连接字符串)

运行调用python manage.py delete_migrations_from_db (如果你这样命名)

import os

import psycopg2
from cacheops import invalidate_all
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import BaseCommand
from django.db import connections


class Command(BaseCommand):
    help = 'Migrate on every database in settings.py'

    def handle(self, *args, **options):
        db_list = settings.DATABASES
        # del db_list['default']

        for db, _ in db_list.items():
            if hasattr(settings, 'CACHE') and settings.CACHE is True:
                invalidate_all()

            # we have the db name, now lets remove the migration tables in each

            try:
                host = os.environ['_HOST']
                user = os.environ['_USER']
                port = os.environ['_PORT']
                password = os.environ['_PASSWORD']

                conn_str = f"host={host} port={port} user={user} password={password}"

                conn = psycopg2.connect(conn_str)
                conn.autocommit = True
                with connections[db].cursor() as cursor:
                    delete_statement = 'DELETE from public.django_migrations'
                    cursor.execute(delete_statement)
                    print(f'Migration table cleared: {db}')
            except psycopg2.Error as ex:
                raise SystemExit(f'Error: {ex}')

        print('Done!')

步骤 4调用python manage.py makemigrations重新初始化初始迁移文件

步骤 5调用python manage.py migrate --database=[YourDB] --fake重新初始化初始迁移文件。 --fake参数允许在数据库中恢复历史记录时不更改数据库结构(如果您想要一个简单的命令在所有数据库中运行此迁移命令,您可以使用类似下面的代码)

使用python manage.py migrate_all --fake调用(取决于命名)

from cacheops import invalidate_all
from django.conf import settings
from django.core.management import call_command
from django.core.management.base import BaseCommand


class Command(BaseCommand):
    help = 'Migrate on every database in settings.py'


    def add_arguments(self, parser):
        parser.add_argument(
            '--fake',
            action='store_true',
            help='fake migrations',
        )

    def handle(self, *args, **options):
        db_list = settings.DATABASES


        for db, _ in db_list.items():
            if hasattr(settings, 'CACHE') and settings.CACHE is True:
                invalidate_all()
            self.stdout.write('Migrating database {}'.format(db))

            if options['fake']:
                call_command('migrate', '--fake', database=db)
            else:
                # no fake, call regularly
                call_command('migrate', database=db)


        self.stdout.write('Done!')

1 在生产环境中重置 Laravel 迁移

大家好 我将尝试尽可能清楚地解释我的问题,如果您不明白我的意思,请随时问我更精确的问题并原谅我的错误,英语不是我的母语。 我的目标 我想再次开始使用迁移,因为我需要创建一个新表,一年后我公司的开发人员通过直接从 phpmyadmin 创建/删除/更新表绕过它们。 你必须知道的事情 上次迁移是 ...

2 迁移:在生产环境中回滚和重置

我只是在学习Laravel的基础知识,并了解有关迁移的知识。 我认为该功能非常酷,但是我想知道迁移的安全性。 根据laracasts的说法,当您创建创建新表的迁移时,该函数的回滚将删除该表。 这是有道理的,但这不是很不安全吗? 通过运行单个命令可能会导致数据丢失。 这仍然是最佳 ...

3 在生产 CMS 方法中应用迁移

我已经阅读了几篇关于在生产中应用迁移的文章。 我很了解它,但我想我想详细了解它。 我也阅读了微软的文档,但它没有给我我正在寻找的东西。 Database.Migrate()方法几乎用于我在网上阅读到的所有相关内容。 它是如何工作的? 没有人解释它。 假设在 CMS 平台中,我想应用新的迁移,在运行 ...

4 Django 网站上的重置密码链接在生产环境中不起作用

我有一个 Django 网站。 它具有用户注册和登录功能。 它目前托管在 pythonanywhere 上。 我正在使用 gmail smtp 服务器从联系表单发送邮件并重置密码。 但是电子邮件中发送的重置链接不起作用。 当我运行本地主机时,链接有效,但在 pythonanywhere 上托管时无效 ...

5 在生产环境中执行基本Django模型迁移的明智方法是什么?

我有一个正在使用的现有django网络应用程序。 我必须从根本上将设计中的一个关键模型迁移到全新的设计中,但是我想缓存该模型的所有现有数据,并在准备部署时将它们迁移到生产中的新记录。 我有能力在一夜之内关闭我的网站几个小时,并做我需要做的一切迁移工作。 我可以执行哪些明智的迁移方式? ...

6 如何在生产中处理 Django 项目中的迁移(Digital Ocean App Platform)?

我已经使用该应用程序平台近 2 个月了。 昨天,我在我的 Django 项目中对数据库表(模型)进行了一些更改。 我将这些更改推送到 Github,我的应用程序成功重新部署。 但是当我打开网站时,我收到“ProgrammingError”,我在现有表中创建的某些字段不存在。 所以,我在 App Pl ...

7 Django迁移冻结并在生产中被杀死

因此,我使用AWS和docker部署了django项目。 当我进行迁移和本地迁移时,一切正常。 但是,当我部署到生产环境并尝试迁移时,迁移会冻结,并且终端将被卡住,直到进程被终止。 没有错误,所以我努力了解发生了什么问题以及如何查找错误。 我还确保在运行迁移之前将站点置于维护模式,以 ...

8 在生产系统中测试帐户和产品

是否值得设计一个系统以期望测试账户和产品在生产中存在并且活跃,或者是否应该没有测试实体的生产数据库污染,即使您的运输人员知道不发送任何发给“测试客户”的盒子? 我已经在规范中实现了具有test =“True”属性的消息传递协议,并想知道现代模式是否应该包含用于标记订单,帐户,事务等的元数据 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM