使用Django和South重命名应用程序

使用Django和South重命名应用程序,django,migration,rename,django-south,Django,Migration,Rename,Django South,我正在将应用程序重命名为更合适的名称。在此过程中,我希望确保正确迁移数据库(重命名数据库表并更改django_content_type或south_migrationhistory中的引用)。我知道如何重命名,但当我尝试重命名应用程序本身时,South无法正确识别迁移历史 不需要的解决方案:在将旧应用程序重命名为新应用程序时,我可以保持旧应用程序/迁移不变,并将新迁移添加到此目录,以将数据库迁移到引用新应用程序 如果可能的话,我希望完全删除目录old\u app。我还没有想到更好的办法来解决这个

我正在将应用程序重命名为更合适的名称。在此过程中,我希望确保正确迁移数据库(重命名数据库表并更改django_content_type或south_migrationhistory中的引用)。我知道如何重命名,但当我尝试重命名应用程序本身时,South无法正确识别迁移历史

不需要的解决方案:在将
旧应用程序
重命名为
新应用程序
时,我可以保持
旧应用程序/迁移
不变,并将新迁移添加到此目录,以将数据库迁移到引用
新应用程序

如果可能的话,我希望完全删除目录
old\u app
。我还没有想到更好的办法来解决这个问题


使用Django South重命名应用程序而不丢失数据的最佳方法是什么?

我不会弄乱应用程序名称。你到处都会提到应用程序名称。URL会话、设置、其他应用程序、模板等

django的设计方式,相应地,假定不需要更改应用程序名称。-说出你想要的项目名称。你哪里都没提到它。更改应用程序名称很麻烦。如果你真的想重命名你的应用程序,你不想要的解决方案是我看到的最好的解决方案


无论如何,如果您愿意,您可以使用python
import as
以不同的名称导入应用程序。

我同意Laksham的观点,您应该避免这种情况。但有时,我们不得不这样做。我过去也曾遇到过这种情况,我就是这样处理的

如果希望避免丢失数据,可以将旧的应用程序数据转储到json文件中

python manage.py dumpdata old_app --natural --indent=4 1> old_app.json
python manage.py loaddata old_app.json
请注意--natural选项,该选项将强制导出内容类型及其自然键(app_name,model)

然后,您可以创建一个小命令来打开这个json文件,并用新的应用程序替换所有旧的应用程序引用

像这样的东西应该有用

class Command(BaseCommand):
    help = u"Rename app in json dump"

    def handle(self, *args, **options):
        try:
            old_app = args[0]
            new_app = args[1]
            filename = args[2]
        except IndexError:
            print u'usage :', __name__.split('.')[-1], 'old_app new_app dumpfile.json'
            return

        try:
            dump_file = open(filename, 'r')
        except IOError:
            print filename, u"doesn't exist"
            return

        objects = json.loads(dump_file.read())
        dump_file.close()

        for obj in objects:
            obj["model"] = obj["model"].replace(old_app, new_app, 1)

            if obj["fields"].has_key("content_type") and (old_app == obj["fields"]["content_type"][0]):
                obj["fields"]["content_type"][0] = new_app

        dump_file = open(filename, 'w')
        dump_file.write(json.dumps(objects, indent=4))
        dump_file.close()
然后重命名应用程序,在已安装的应用程序中更改名称

然后,您应该删除所有南方迁移,重新生成并为新应用程序应用初始迁移。然后运行SQL命令:

update django_content_type set app_label='new_app' where app_label='old_app'
然后为新应用程序启动一个south migrate,以创建表并加载json文件

python manage.py dumpdata old_app --natural --indent=4 1> old_app.json
python manage.py loaddata old_app.json
我在一个项目上做过类似的事情,看起来效果不错


我希望这有帮助

可以重命名应用程序。 作为项目示例,请参见:

基本上,有两次迁移。首先使用
db.rename_table()
重命名表,然后更新内容类型。 这可以通过检查
如果不是db.dry\u run:
组合到一个迁移中。请参阅,以获取此示例

对于初始迁移,可以直接重命名现有表(如果存在):

if 'old_app_table_name' in connection.introspection.table_names():
    db.rename_table('old_app_table_name', 'new_app_table_name')
else:
    # Create new app tables directly.
对于迁移次数较多的表,可能需要检查是否已应用旧迁移名称:

from south.models import MigrationHistory
if MigrationHistory.objects.exists(app_name='old_app', migration='0001_initial'):
    return

最后,我建议使用IDE(例如PyCharm试用版)来重命名包(右键单击,重构->重命名包),因为它将为您更新整个应用程序的所有用法,包括URLconf、设置和导入。

在插入一些代码之后,我想到了这个。你应该照顾好它。

免责声明:这个答案适用于那些不关心迁移历史,并且已经因为重命名应用程序而变得一团糟,完全忘记迁移的人(就像我一样)。 为我工作

在更改文件夹名称、处理代码中的所有导入以及在settings.INSTALLED_APPS中更改相应的应用程序名称后,只需删除以前的所有迁移文件夹。然后做一个这样的开头

manage.py schemamigration new_app --initial
然后,在应用它时,像这样假装它

manage.py migrate new_app 0001 --fake
别忘了--假装,否则可能会丢失数据

所有进一步的迁移都可以正常工作

manage.py migrate new_app 0002
此外,您还可以从south_migrationhistory中删除app_name=“old_app”

免责声明:这可能不是一种理想的方法,但这肯定比其他地方/之前建议的许多其他方法更简单

如果您正在使用PyCharm,您可以尝试以下解决方案

  • 右键单击Django项目中的应用程序目录
  • 重构
    >
    重命名
    >输入新应用程序名称(
    新应用程序
  • 选中
    搜索引用
    在注释和字符串中搜索
    ,范围
    项目文件
    重构
  • 这将显示文件重命名的位置>
    Refactor
  • 如果您对项目名称不满意,也可以对项目名称执行同样的操作
现在问题来了

python manage.py makemigrations

python manage.py迁移

这会怎么样

  • 这将基本上创建一个新应用程序,并将所有迁移应用到此新应用程序
  • 但是,您的数据仍然驻留在旧应用程序中(
    old\u app
  • 我们需要把它放到
    新的应用程序
    表中
在数据库中,我们需要

  • 通过从
    旧应用程序
    表复制数据,将数据插入
    新应用程序
  • INSERT INTO new_app_table_name从旧_app_table_name中选择*

    您必须对应用程序中的所有模型/表格执行此操作

  • 重置表的顺序,以避免在django中出现主键冲突错误
  • SELECT setval('new_app_table_name_id_seq',(从new_app_table_name中选择MAX(id))

    您必须对步骤1中的所有表执行此操作

    我不想无知地宣称这应该像这样容易。我的项目和模型结构相当复杂,但这对我来说很有吸引力。然而,如果您的项目结构太复杂,那么只有部分内容可能适合您

    计算机科学中只有两个难题:缓存