Преглед изворни кода

[desktop] Delete duplicated documents,tags,permissions before creating unique index

Erick Tryzelaar пре 10 година
родитељ
комит
ad42a17

+ 29 - 2
desktop/core/src/desktop/migrations/0013_auto__add_unique_documenttag_owner_tag.py

@@ -1,13 +1,40 @@
 # -*- coding: utf-8 -*-
+import logging
 from south.utils import datetime_utils as datetime
 from south.db import db
 from south.v2 import SchemaMigration
-from django.db import models
+from django.db import models, transaction
+
+from desktop.models import DocumentTag
 
 
 class Migration(SchemaMigration):
 
     def forwards(self, orm):
+        # If there are duplicated document tags, we'll have an error when we
+        # try to create this index. So to protect against that, we should
+        # delete those documents before we create the index.
+        with transaction.atomic():
+            duplicated_records = DocumentTag.objects \
+                .values('owner_id', 'tag') \
+                .annotate(id_count=models.Count('id')) \
+                .filter(id_count__gt=1)
+
+            # Delete all but the first document.
+            for record in duplicated_records:
+                docs = DocumentTag.objects \
+                    .values_list('id', flat=True) \
+                    .filter(
+                        owner_id=record['owner_id'],
+                        tag=record['tag'],
+                    )[1:]
+
+                docs = list(docs)
+
+                logging.warn('Deleting tags %s' % docs)
+
+                DocumentTag.objects.filter(id__in=docs).delete()
+
         # Adding unique constraint on 'DocumentTag', fields ['owner', 'tag']
         db.create_unique(u'desktop_documenttag', ['owner_id', 'tag'])
 
@@ -112,4 +139,4 @@ class Migration(SchemaMigration):
         }
     }
 
-    complete_apps = ['desktop']
+    complete_apps = ['desktop']

+ 29 - 2
desktop/core/src/desktop/migrations/0014_auto__add_unique_document_content_type_object_id.py

@@ -1,13 +1,40 @@
 # -*- coding: utf-8 -*-
+import logging
 from south.utils import datetime_utils as datetime
 from south.db import db
 from south.v2 import SchemaMigration
-from django.db import models
+from django.db import models, transaction
+
+from desktop.models import Document
 
 
 class Migration(SchemaMigration):
 
     def forwards(self, orm):
+        # If there are duplicated documents, we'll have an error when we try to
+        # create this index. So to protect against that, we should delete those
+        # documents before we create the index.
+        with transaction.atomic():
+            duplicated_records = Document.objects \
+                .values('content_type_id', 'object_id') \
+                .annotate(id_count=models.Count('id')) \
+                .filter(id_count__gt=1)
+
+            # Delete all but the first document.
+            for record in duplicated_records:
+                docs = Document.objects \
+                    .values_list('id', flat=True) \
+                    .filter(
+                        content_type_id=record['content_type_id'],
+                        object_id=record['object_id'],
+                    )[1:]
+
+                docs = list(docs)
+
+                logging.warn('Deleting documents %s' % docs)
+
+                Document.objects.filter(id__in=docs).delete()
+
         # Adding unique constraint on 'Document', fields ['content_type', 'object_id']
         db.create_unique(u'desktop_document', ['content_type_id', 'object_id'])
 
@@ -112,4 +139,4 @@ class Migration(SchemaMigration):
         }
     }
 
-    complete_apps = ['desktop']
+    complete_apps = ['desktop']

+ 29 - 2
desktop/core/src/desktop/migrations/0015_auto__add_unique_documentpermission_doc_perms.py

@@ -1,13 +1,40 @@
 # -*- coding: utf-8 -*-
+import logging
 from south.utils import datetime_utils as datetime
 from south.db import db
 from south.v2 import SchemaMigration
-from django.db import models
+from django.db import models, transaction
+
+from desktop.models import DocumentPermission
 
 
 class Migration(SchemaMigration):
 
     def forwards(self, orm):
+        # If there are duplicated document permissions, we'll have an error
+        # when we try to create this index. So to protect against that, we
+        # should delete those documents before we create the index.
+        with transaction.atomic():
+            duplicated_records = DocumentPermission.objects \
+                .values('doc_id', 'perms') \
+                .annotate(id_count=models.Count('id')) \
+                .filter(id_count__gt=1)
+
+            # Delete all but the first document.
+            for record in duplicated_records:
+                docs = DocumentPermission.objects \
+                    .values_list('id', flat=True) \
+                    .filter(
+                        doc_id=record['doc_id'],
+                        perms=record['perms'],
+                    )[1:]
+
+                docs = list(docs)
+
+                logging.warn('Deleting permissions %s' % docs)
+
+                DocumentPermission.objects.filter(id__in=docs).delete()
+
         # Adding unique constraint on 'DocumentPermission', fields ['doc', 'perms']
         db.create_unique(u'desktop_documentpermission', ['doc_id', 'perms'])
 
@@ -112,4 +139,4 @@ class Migration(SchemaMigration):
         }
     }
 
-    complete_apps = ['desktop']
+    complete_apps = ['desktop']

+ 34 - 2
desktop/core/src/desktop/migrations/0016_auto__add_unique_document2_uuid_version_is_history.py

@@ -1,13 +1,45 @@
 # -*- coding: utf-8 -*-
+import logging
 from south.utils import datetime_utils as datetime
 from south.db import db
 from south.v2 import SchemaMigration
-from django.db import models
+from django.db import models, transaction
+
+from desktop.models import Document2
 
 
 class Migration(SchemaMigration):
 
     def forwards(self, orm):
+        # As opposed to Document1, we can't just delete Document2 documents if
+        # there is a duplication because it actually holds data. So instead
+        # we'll just find duplications and emit a better error message.
+        with transaction.atomic():
+            duplicated_records = Document2.objects \
+                .values('uuid', 'version', 'is_history') \
+                .annotate(id_count=models.Count('id')) \
+                .filter(id_count__gt=1)
+
+            duplicated_records = list(duplicated_records)
+            duplicated_ids = []
+
+            for record in duplicated_records:
+                docs = Document2.objects \
+                    .values_list('id', flat=True) \
+                    .filter(
+                        uuid=record['uuid'],
+                        version=record['version'],
+                        is_history=record['is_history'],
+                    )
+
+                duplicated_ids.extend(docs)
+
+            if duplicated_records:
+                msg = 'Found duplicated Document2 records! %s. ' \
+                    'This will require manual merging of the records' % duplicated_ids
+                logging.error(msg)
+                raise RuntimeError(msg)
+
         # Adding unique constraint on 'Document2', fields ['uuid', 'version', 'is_history']
         db.create_unique(u'desktop_document2', ['uuid', 'version', 'is_history'])
 
@@ -112,4 +144,4 @@ class Migration(SchemaMigration):
         }
     }
 
-    complete_apps = ['desktop']
+    complete_apps = ['desktop']