109 lines
4.1 KiB
Python
109 lines
4.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Generated by Django 1.9.6 on 2016-06-01 16:00
|
|
from __future__ import unicode_literals
|
|
|
|
from collections import defaultdict
|
|
from django.db import DEFAULT_DB_ALIAS, migrations, models, router
|
|
from django.apps import apps as live_apps
|
|
|
|
|
|
def de_dupe_version_table(apps, schema_editor):
|
|
"""
|
|
Removes some duplicate Version models that may have crept into the database and will prevent the
|
|
unique index being added by migration 0004.
|
|
"""
|
|
db_alias = schema_editor.connection.alias
|
|
Version = apps.get_model("reversion", "Version")
|
|
keep_version_ids = Version.objects.using(db_alias).order_by().values_list(
|
|
# Group by the unique constraint we intend to enforce.
|
|
"revision_id",
|
|
"content_type_id",
|
|
"object_id",
|
|
).annotate(
|
|
# Add in the most recent id for each duplicate row.
|
|
max_pk=models.Max("pk"),
|
|
).values_list("max_pk", flat=True)
|
|
# Do not do anything if we're keeping all ids anyway.
|
|
if keep_version_ids.count() == Version.objects.using(db_alias).all().count():
|
|
return
|
|
# Delete all duplicate versions. Can't do this as a delete with subquery because MySQL doesn't like running a
|
|
# subquery on the table being updated/deleted.
|
|
delete_version_ids = list(Version.objects.using(db_alias).exclude(
|
|
pk__in=keep_version_ids,
|
|
).values_list("pk", flat=True))
|
|
Version.objects.using(db_alias).filter(
|
|
pk__in=delete_version_ids,
|
|
).delete()
|
|
|
|
|
|
def set_version_db(apps, schema_editor):
|
|
"""
|
|
Updates the db field in all Version models to point to the correct write
|
|
db for the model.
|
|
"""
|
|
db_alias = schema_editor.connection.alias
|
|
Version = apps.get_model("reversion", "Version")
|
|
content_types = Version.objects.using(db_alias).order_by().values_list(
|
|
"content_type_id",
|
|
"content_type__app_label",
|
|
"content_type__model"
|
|
).distinct()
|
|
model_dbs = defaultdict(list)
|
|
for content_type_id, app_label, model_name in content_types:
|
|
# We need to be able to access all models in the project, and we can't
|
|
# specify them up-front in the migration dependencies. So we have to
|
|
# just get the live model. This should be fine, since we don't actually
|
|
# manipulate the live model in any way.
|
|
try:
|
|
model = live_apps.get_model(app_label, model_name)
|
|
except LookupError:
|
|
# If the model appears not to exist, play it safe and use the default db.
|
|
db = "default"
|
|
else:
|
|
db = router.db_for_write(model)
|
|
model_dbs[db].append(content_type_id)
|
|
# Update db field.
|
|
# speedup for case when there is only default db
|
|
if DEFAULT_DB_ALIAS in model_dbs and len(model_dbs) == 1:
|
|
Version.objects.using(db_alias).update(db=DEFAULT_DB_ALIAS)
|
|
else:
|
|
for db, content_type_ids in model_dbs.items():
|
|
Version.objects.using(db_alias).filter(
|
|
content_type__in=content_type_ids
|
|
).update(db=db)
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
|
|
dependencies = [
|
|
('reversion', '0002_auto_20141216_1509'),
|
|
]
|
|
|
|
operations = [
|
|
migrations.RemoveField(
|
|
model_name='revision',
|
|
name='manager_slug',
|
|
),
|
|
migrations.RemoveField(
|
|
model_name='version',
|
|
name='object_id_int',
|
|
),
|
|
migrations.AlterField(
|
|
model_name='version',
|
|
name='object_id',
|
|
field=models.CharField(help_text='Primary key of the model under version control.', max_length=191),
|
|
),
|
|
migrations.AlterField(
|
|
model_name='revision',
|
|
name='date_created',
|
|
field=models.DateTimeField(db_index=True, help_text='The date and time this revision was created.', verbose_name='date created'),
|
|
),
|
|
migrations.AddField(
|
|
model_name='version',
|
|
name='db',
|
|
field=models.CharField(null=True, help_text='The database the model under version control is stored in.', max_length=191),
|
|
),
|
|
migrations.RunPython(de_dupe_version_table),
|
|
migrations.RunPython(set_version_db),
|
|
]
|