将现有的auth.User数据迁移到新的Django 1.5自定义用户模型?

Ben*_*rts 34 django postgresql django-south django-1.5

我不想破坏我网站上的所有用户.但我想利用Django 1.5的自定义可插拔用户模型.这是我的新用户模型:

class SiteUser(AbstractUser):
    site = models.ForeignKey(Site, null=True)
Run Code Online (Sandbox Code Playgroud)

在新的安装上我的新模型都可以使用(我还有其他代码,还有一个很好的理由 - 所有这些都与此无关).但是,如果我把它放在我的实时网站上并同步和迁移,我将丢失所有用户,或者至少他们将处于与为我的新模型创建的新表不同的孤立表中.

我对南方很熟悉,但基于这篇文章和我的一些试验,似乎它的数据迁移目前还不适合这种特定的迁移.所以我正在寻找一些方法来让South为此工作或者为我的每个服务器(Postgres 9.2)运行的一些非南迁移(原始SQL,dumpdata/loaddata或其他)迁移用户一旦创建了新表,而旧的auth.User表仍在数据库中.

Tho*_*mas 49

South无法为您进行此迁移,但您需要聪明并分阶段完成.这是一步一步的指南:(本指南以子类为前提AbstractUser,而不是AbstractBaseUser)

  1. 在进行切换之前,请确保在包含自定义用户模型的应用程序中启用了南支持(为了指南,我们将调用它accounts和模型User).此时您还不应该拥有自定义用户模型.

    $ ./manage.py schemamigration accounts --initial
    Creating migrations directory at 'accounts/migrations'...
    Creating __init__.py in 'accounts/migrations'...
    Created 0001_initial.py.
    
    $ ./manage.py migrate accounts [--fake if you've already syncdb'd this app]
     Running migrations for accounts:
     - Migrating forwards to 0001_initial.
     > accounts:0001_initial
     - Loading initial data for accounts.
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在帐户应用中创建新的空白用户迁移.

    $ ./manage.py schemamigration accounts --empty switch_to_custom_user
    Created 0002_switch_to_custom_user.py.
    
    Run Code Online (Sandbox Code Playgroud)
  3. Useraccounts应用中创建自定义模型,但请确保将其定义为:

    class SiteUser(AbstractUser): pass
    
    Run Code Online (Sandbox Code Playgroud)
  4. 使用以下代码填写空白迁移.

    # encoding: utf-8
    from south.db import db
    from south.v2 import SchemaMigration
    
    class Migration(SchemaMigration):
    
        def forwards(self, orm):
            # Fill in the destination name with the table name of your model
            db.rename_table('auth_user', 'accounts_user')
            db.rename_table('auth_user_groups', 'accounts_user_groups')
            db.rename_table('auth_user_user_permissions', 'accounts_user_user_permissions')
    
        def backwards(self, orm):
            db.rename_table('accounts_user', 'auth_user')
            db.rename_table('accounts_user_groups', 'auth_user_groups')
            db.rename_table('accounts_user_user_permissions', 'auth_user_user_permissions')
    
        models = { ....... } # Leave this alone
    
    Run Code Online (Sandbox Code Playgroud)
  5. 运行迁移

    $ ./manage.py migrate accounts
     - Migrating forwards to 0002_switch_to_custom_user.
     > accounts:0002_switch_to_custom_user
     - Loading initial data for accounts.
    
    Run Code Online (Sandbox Code Playgroud)
  6. 立即对您的用户模型进行任何更改.

    # settings.py
    AUTH_USER_MODEL = 'accounts.User'
    
    # accounts/models.py
    class SiteUser(AbstractUser):
        site = models.ForeignKey(Site, null=True)
    
    Run Code Online (Sandbox Code Playgroud)
  7. 为此更改创建并运行迁移

    $ ./manage.py schemamigration accounts --auto
     + Added field site on accounts.User
    Created 0003_auto__add_field_user_site.py.
    
    $ ./manage.py migrate accounts
     - Migrating forwards to 0003_auto__add_field_user_site.
     > accounts:0003_auto__add_field_user_site
     - Loading initial data for accounts.
    
    Run Code Online (Sandbox Code Playgroud)

老实说,如果您已经很好地了解了您的设置并且已经使用了南方,那么就应该像将以下迁移添加到您的帐户模块一样简单.

# encoding: utf-8
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Fill in the destination name with the table name of your model
        db.rename_table('auth_user', 'accounts_user')
        db.rename_table('auth_user_groups', 'accounts_user_groups')
        db.rename_table('auth_user_permissions', 'accounts_user_permissions')
        # == YOUR CUSTOM COLUMNS ==
        db.add_column('accounts_user', 'site_id',
            models.ForeignKey(orm['sites.Site'], null=True, blank=False)))

    def backwards(self, orm):
        db.rename_table('accounts_user', 'auth_user')
        db.rename_table('accounts_user_groups', 'auth_user_groups')
        db.rename_table('accounts_user_user_permissions', 'auth_user_user_permissions')
        # == YOUR CUSTOM COLUMNS ==
        db.remove_column('accounts_user', 'site_id')

    models = { ....... } # Leave this alone
Run Code Online (Sandbox Code Playgroud)

编辑2/5/13:为auth_user_group表添加了重命名.由于db约束,FK将自动更新以指向正确的表,但是M2M字段的表名是从2个端表的名称生成的,并且需要以这种方式手动更新.

编辑2:感谢@Tuttle和@ pix0r进行更正.

  • 是不是要迁移auth_user_groups和auth_user_permissions? (2认同)

Jac*_*edd 16

我这种令人难以置信的懒惰方式:

  1. 创建一个新模型(User),扩展AbstractUser.在新模型中,在它的Meta中,覆盖db_table并设置为'auth_user'.

  2. 使用South创建初始迁移.

  3. 迁移,但--fake在运行迁移时使用虚假迁移.

  4. 添加新字段,创建迁移,正常运行.

这超出了懒惰,但有效.您现在拥有符合1.5的用户模型,它只使用旧的用户表.您还有适当的迁移历史记录.

您可以稍后通过手动迁移修复此问题以重命名表.