使用south重命名Django模型类名和相应的外键,而不会丢失数据

ne5o7dgx  于 2023-08-08  发布在  Go
关注(0)|答案(2)|浏览(98)

以下是我的模型:

class myUser_Group(models.Model):
    name = models.CharField(max_length=100)

class Channel(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=1000)
    belongs_to_group = models.ManyToManyField(myUser_Group)

class Video(models.Model):
    video_url = models.URLField(max_length=300) 
    belongs_to_channel = models.ManyToManyField(Channel)
    description = models.CharField(max_length=1000)
    tags = TagField()

class UserProfile(models.Model):
       user = models.OneToOneField(User)

class User_History(models.Model):
    date_time = models.DateTimeField()
    user = models.ForeignKey(UserProfile, null=True, blank=True)
    videos_watched = models.ManyToManyField(Video)

字符串
我只是想删除所有类名中的下划线,这样User_History看起来就像UserHistory,外键也应该更新。我试着使用南方,但在文档中找不到。
一种方法是导出数据,卸载south,删除迁移,重命名表,然后再次导入数据。还有别的办法吗?

gcmastyq

gcmastyq1#

你可以使用南。
在这个例子中,我有一个名为usergroups的应用程序,模型如下:

class myUser_Group(models.Model):
    name = models.CharField(max_length=100)

字符串
我想那里已经在南方的移民控制之下了
更改模型名称:

class MyUserGroup(models.Model):
    name = models.CharField(max_length=100)


并从南方造成一个空的迁徙

$ python manage.py schemamigration usergroups model_name_change --empty


这将为您创建一个框架迁移文件,以指定发生的情况。如果我们编辑它,使其看起来像这样(在本例中,此文件将位于app_name/migrations/文件夹中-- usergroups/migrations/):

import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Change the table name from the old model name to the new model name
        # ADD THIS LINE (using the correct table names)
        db.rename_table('usergroups_myuser_group', 'usergroups_myusergroup')

    def backwards(self, orm):
        # Provide a way to do the migration backwards by renaming the other way
        # ADD THIS LINE (using the correct table names)
        db.rename_table('usergroups_myusergroup', 'usergroups_myuser_group')

    models = {
        'usergroups.myusergroup': {
            'Meta': {'object_name': 'MyUserGroup'},
            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
        }
    }

    complete_apps = ['usergroups']


forwards方法中,我们重命名数据库表名,以匹配django ORM将使用新模型名称查找的内容。我们反转了backwards中的更改,以确保在需要时可以回退迁移。
运行迁移,无需导入/导出现有数据:
$ python manage.py
剩下的唯一步骤是更新模型中引用myUser_Group的外键和多对多列,并更改为引用MyUserGroup。

w9apscun

w9apscun2#

mmcnickle的解决方案可能可行,似乎合理,但我更喜欢两步的过程。在第一步中,更改表名。
在您的模型中,请确保您的新表名位于:

class Meta:
        db_table = new_table_name'

字符串
然后像mmcnickle建议的那样,创建一个自定义迁移:

python manage.py schemamigration xyz migration_name --empty


你可以在这里阅读更多:https://docs.djangoproject.com/en/dev/ref/models/options/
现在,在您的自定义迁移中,还可以添加一行代码来向前和向后重命名您的表:

db.rename_table("old_table_name","new_table_name")


这足以迁移和更改表名,但如果您之前一直在使用Class Meta自定义表名,则必须做更多的工作。所以我会说,作为一个规则,只是为了安全起见,在迁移文件中搜索“old_table_name”,并将找到的任何条目更改为新的表名。例如,如果您以前使用的是Class Meta自定义表名,则可能会看到:

'Meta': {'object_name': 'ModelNameYouWillChangeNext', 'db_table': "u'old_table_name'"},


因此,您需要将旧表名更改为新表名。
现在,您可以使用以下工具进行迁移:

python manage.py migrate xyz


此时,你的应用程序应该运行了,因为你所做的就是更改表名并告诉Django查找新的表名。
第二步是更改模型名称。这一点的难度取决于你的应用程序,但基本上你只需要将所有引用旧模型名称的代码更改为引用新模型名称的代码。如果出于组织的目的在其中使用了旧的模型名称,那么您可能还需要更改一些文件名和目录名。
这样做之后,您的应用程序应该运行良好。至此,您的任务基本完成,您的应用程序应该可以使用新的模型名称和新的表名称正常运行。使用South遇到的唯一问题是,下次使用它的自动检测功能创建迁移时,它会尝试删除旧表并从头开始创建新表,因为它检测到了新的模型名称。要解决此问题,您需要创建另一个自定义迁移:

python manage.py schemamigration xyz tell_south_we_changed_the_model_name_for_old_model_name --empty


好的事情是在这里你什么都不做,因为你已经改变了你的模型名称,所以南拿起这个。只需在向前和向后迁移中使用“pass”即可:

python manage.py migrate xyz


什么都没做,南现在意识到它是最新的。试试看:

python manage.py schemamigration xyz --auto


你应该能看到它没有检测到任何变化

相关问题