Django迁移在django初始化期间失败 [英] Django Migrations fail during django initialization

查看:264
本文介绍了Django迁移在django初始化期间失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

设置



几个月前,我将应用程序从Django 1.6升级到1.7,然后升级到1.8,现在我正在努力达到1.9。



在迁移时,我发现了一个非常讨厌的数据库状态依赖实例 - 一个管理方法(不太好)的自定义用户模型调用 django.contrib .auth.models.Group 。让人惊讶。所以当我设置连续集成管道时,我设法解决了数据迁移问题,一切都很棒。



迁移如下所示:

 #为简洁省略#import语句

def seed_groups(apps,schema_editor):
Group = apps。 get_model('auth','Group')
Group.objects.get_or_create(name ='group1')
Group.objects.get_or_create(name ='group2')
Group.objects。 get_or_create(name ='group3')

class Migration(migrations.Migration):
dependencies = [('auth','0001_initial')]
operations = [migrations。 RunPython(seed_groups)]

好的,这不是很好 - 使用 get_or_create 这里允许我们连接一个已经有数据的数据库,而不会使Postgres对它已经拥有的行进行插入。尽管如此,我们一直都是快乐的露营者,快速进行测试,我们的环境都没有任何问题。



扭曲



所以我一直在运行我的测试和修复deprecations,更新库,blah blah blah。所以,令人惊讶的是,我的CI环境(一个适度受欢迎的服务)无法在迁移步骤中建立,只有Django版本从1.8升级到1.9。



我检查过没有某种缓存的依赖关系链问题(我们正在加载所有正确的库),但是错误的追溯非常熟悉....

  django.db.utils.ProgrammingError:关系auth_group不存在
LINE 1:...选择auth_group。id,auth_group 。nameFROMauth_grou ...
^

完整追溯可在这里: https://gist.github.com/alexkahn/b63c41904809cbe53962dc104e4067f0



此错误正在从运行 python manage.py migrate --no-input



< h2>我以无效的方式解决了这个问题:

修改看到d_groups函数如下:

  def seed_groups(apps,schema_editor):
#same
db_alias = schema_editor .connection.alias
Group.objects.using(db_alias).get_or_create(name ='group1')
#等...

为此应用程序向我的0001迁移添加一个 initial = True 类属性。



将所有迁移压缩为一个。



将我已安装的应用列表直接指向此应用的AppConfig子类。



我在想些什么,我不知道。



底线



任何人都知道为什么会突然改变?有没有什么超级明显的我觉得太难了?

解决方案

所以这样一来,不如Django那么好办法。



所以我们在这里有一个模特经理:

  class UserManager(BaseUserManager):
def users_in_group1(self):
return Group.objects.get(name ='group1')。user_set.filter()

它返回一个直接与auth.models.Group模型交互的查询集。模型之间的紧密耦合导致Django需要在任何表创建之前解决该关系。



简单更改为:

  def users_in_group1(self):
return self.filter(groups__name ='group1')

允许迁移运行没有问题。


The setup

A few months ago I upgraded an app from Django 1.6 to 1.7 then 1.8 and now I'm working on getting up to 1.9.

While wrangling with migrations I uncovered a pretty nasty instance of database state dependency - a management method on the (not so great) custom user model calls django.contrib.auth.models.Group. Yikes. So when I set up the Continuous Integration pipeline I managed to solve the problem with a data migration and everything was great.

The migration looks like this:

# import statements left out for brevity

def seed_groups(apps, schema_editor):
    Group = apps.get_model('auth', 'Group')
    Group.objects.get_or_create(name='group1')
    Group.objects.get_or_create(name='group2')
    Group.objects.get_or_create(name='group3')

class Migration(migrations.Migration):
    dependencies = [('auth', '0001_initial')]
    operations = [migrations.RunPython(seed_groups)]

Okay, so that's not totally great - the usage of get_or_create here allows us to hook up a database that already has data in it without making Postgres get super upset about asking it to insert rows it already has. This works though and we've been happy campers with tests running merrily and none of our environments have had any issues.

The twist

So I've been running my tests and fixing deprecations, updating libraries, blah blah blah. So it came as a surprise that my CI environment (a moderately popular service) is failing to build at the migration step, only since the Django version changed from 1.8 to 1.9.

I've checked that there isn't some sort of cached dependency chain issue (we're loading all the right libraries) but the traceback from the error is very familiar....

django.db.utils.ProgrammingError: relation "auth_group" does not exist
LINE 1: ...ELECT "auth_group"."id", "auth_group"."name" FROM "auth_grou...
^

Full traceback available here: https://gist.github.com/alexkahn/b63c41904809cbe53962dc104e4067f0

This error is cropping up from running python manage.py migrate --no-input

Things I've done in futile attempts to resolve the issue:

Modifying the seed_groups function like so:

def seed_groups(apps, schema_editor):
    # same
    db_alias = schema_editor.connection.alias
    Group.objects.using(db_alias).get_or_create(name='group1')
    # etc...

Adding an initial = True class attribute to my 0001 migration for this app.

Squash all of the migrations into one.

Pointing my installed apps list directly to this app's AppConfig subclass.

What I was thinking for some of those, I don't know.

Bottom Line

Anyone have a clue why this would suddenly change? Is there something super obvious that I am thinking too hard about?

解决方案

So this pulled out some new havoc from a...not so great way to do things with Django.

So we have a model manager here:

class UserManager(BaseUserManager):
    def users_in_group1(self):
        return Group.objects.get(name='group1').user_set.filter()

It's returning a queryset that directly interacts with the auth.models.Group model. Tight coupling between models here resulted in Django needing to resolve that relation before any tables were created.

A simple change to:

def users_in_group1(self):
    return self.filter(groups__name='group1')

Allows the migrations to run without issue.

这篇关于Django迁移在django初始化期间失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆