2015-07-21 3 views
7

In einem Django 1.8-Projekt, ich habe eine Migration, die gut funktionierte, when it had the following code:Die Django-Migration schlägt mit "__fake __. DoesNotExist: Abfrage für Übereinstimmungsüberprüfung existiert nicht" fehl.

# -*- coding: utf-8 -*- 
from __future__ import unicode_literals 

from django.db import migrations 
from django.conf import settings 


def update_site_forward(apps, schema_editor): 
    """Add group osmaxx.""" 
    Group = apps.get_model("auth", "Group") 
    Group.objects.create(name=settings.OSMAXX_FRONTEND_USER_GROUP) 


def update_site_backward(apps, schema_editor): 
    """Revert add group osmaxx.""" 
    Group = apps.get_model("auth", "Group") 
    Group.objects.get(name=settings.OSMAXX_FRONTEND_USER_GROUP).delete() 


class Migration(migrations.Migration): 

    dependencies = [ 
     ('auth', '0001_initial'), 
    ] 

    operations = [ 
     migrations.RunPython(update_site_forward, update_site_backward), 
    ] 

Diese Gruppe in einer Migration erstellt wird, weil es in allen Installationen des Web-App zur Verfügung stehen soll. Um es nützlich, wollte ich auch eine Standardberechtigung geben, also habe ich update_site_forward zu:

def update_site_forward(apps, schema_editor): 
    """Add group osmaxx.""" 
    Group = apps.get_model("auth", "Group") 
    Permission = apps.get_model("auth", "Permission") 
    ContentType = apps.get_model("contenttypes", "ContentType") 
    ExtractionOrder = apps.get_model("excerptexport", "ExtractionOrder") 
    group = Group.objects.create(name=settings.OSMAXX_FRONTEND_USER_GROUP) 
    content_type = ContentType.objects.get_for_model(ExtractionOrder) 
    permission = Permission.objects.get(codename='add_extractionorder', 
             content_type=content_type) # line 16 
    group.permissions.add(permission) 

und Migration.dependencies zu:

dependencies = [ 
     ('contenttypes', '0002_remove_content_type_name'), 
     ('excerptexport', '0001_initial'), 
     ('auth', '0001_initial'), 
    ] 

Während die Migration der Anwendung (nach dem ersten Zurücksetzen it) (python3 manage.py migrate auth 0001 && python3 managy.py migrate) gearbeitet, eine neu erstellte PostgreSQL-Datenbank mit dieser Migration und allen anderen Migrationen (python3 manage.py migrate) ausfällt:

Operations to perform: 
    Synchronize unmigrated apps: debug_toolbar, django_extensions, messages, humanize, social_auth, kombu_transport_django, staticfiles 
    Apply all migrations: excerptexport, admin, sites, contenttypes, sessions, default, stored_messages, auth 
Synchronizing apps without migrations: 
    Creating tables... 
    Running deferred SQL... 
    Installing custom SQL... 
Running migrations: 
    Rendering model states... DONE 
    Applying auth.0002_add_default_usergroup_osmaxx...Traceback (most recent call last): 
    File "manage.py", line 17, in <module> 
    execute_from_command_line(sys.argv) 
    File "/usr/local/lib/python3.4/dist-packages/django/core/management/__init__.py", line 338, in execute_from_command_line 
    utility.execute() 
    File "/usr/local/lib/python3.4/dist-packages/django/core/management/__init__.py", line 330, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/usr/local/lib/python3.4/dist-packages/django/core/management/base.py", line 393, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "/usr/local/lib/python3.4/dist-packages/django/core/management/base.py", line 444, in execute 
    output = self.handle(*args, **options) 
    File "/usr/local/lib/python3.4/dist-packages/django/core/management/commands/migrate.py", line 221, in handle 
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial) 
    File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/executor.py", line 110, in migrate 
    self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial) 
    File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/executor.py", line 148, in apply_migration 
    state = migration.apply(state, schema_editor) 
    File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/migration.py", line 115, in apply 
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state) 
    File "/usr/local/lib/python3.4/dist-packages/django/db/migrations/operations/special.py", line 183, in database_forwards 
    self.code(from_state.apps, schema_editor) 
    File "/home/osmaxx/source/osmaxx/contrib/auth/migrations/0002_add_default_usergroup_osmaxx.py", line 16, in update_site_forward 
    permission = Permission.objects.get(codename='add_extractionorder', content_type=content_type) 
    File "/usr/local/lib/python3.4/dist-packages/django/db/models/manager.py", line 127, in manager_method 
    return getattr(self.get_queryset(), name)(*args, **kwargs) 
    File "/usr/local/lib/python3.4/dist-packages/django/db/models/query.py", line 334, in get 
    self.model._meta.object_name 
__fake__.DoesNotExist: Permission matching query does not exist. 

Was mache ich falsch?

+0

Hinweis: Der vollständige Code des Projekts (ohne die erwähnte Änderung) ist [auf GitHub] verfügbar (https://github.com/geometalab/osmaxx/tree/378ddc5043f1fd80727067de19316f30d1f725b5). Die erwähnte Migration ist [osmaxx-py/osmaxx/contrib/auth/migrationen/0002_add_default_usergroup_osmaxx.py] (https://github.com/geometalab/osmaxx/blob/378ddc5043f1fd80727067de19316f30d1f725b5/osmaxx-py/osmaxx/contrib/auth/migrations/ 0002_add_default_usergroup_osmaxx.py) Aber bitte kommentieren Sie, ob da etwas, was in der Frage nicht erwähnt ist, für die Beantwortung der Frage relevant ist, damit ich sie in die Frage einbeziehen kann. –

Antwort

10

Die Standardberechtigungen werden in einem post_migrate Signalhandler, nach die Migrationen ausgeführt wurden erstellt. Wenn Ihr aktualisierter Code als Teil des zweiten manage.py migrate-Laufs ausgeführt wird, wird das kein Problem aber es ist ein Problem in der Testsuite und jeder neuen Bereitstellung.

Die einfache Lösung ist es, diese Linie zu ändern:

permission = Permission.objects.get(codename='add_extractionorder', 
            content_type=content_type) # line 16 

dazu:

permission, created = Permission.objects.get_or_create(codename='add_extractionorder', 
               content_type=content_type) 

Die Signal-Handler, der die Standardberechtigungen erstellt wird nie eine doppelte Erlaubnis erstellen, so ist es sicher zu erstelle es, wenn es nicht bereits existiert.

+0

Ah, also Berechtigungen werden nach * allen * Migrationen erstellt, nicht nach * jeder einzelnen * Migration? –

+0

Das 'post_migrate'-Signal wird jedes Mal ausgelöst, wenn der Befehl' manage.py migrate' abgeschlossen wird. Wenn Sie also alle Migrationen gleichzeitig anwenden, wird es ausgelöst, nachdem _alle_ Migrationen ausgeführt wurden. – knbk

+0

Diese Antwort hat eine Umgehungslösung für diesen Artikel: http://stackoverflow.com/questions/31735042/adding-django-admin-permissions-in-a-migration-permission-matching-query-does-n –

Verwandte Themen