from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('osf', '0083_add_file_fields_for_target'),
    ]

    operations = [
        migrations.RunSQL(
            ["""
        UPDATE osf_basefilenode
        SET target_object_id = node_id;
        UPDATE osf_basefilenode
        SET target_content_type_id = (SELECT id FROM django_content_type WHERE app_label = 'osf' AND model = 'abstractnode');
        """], ["""
        UPDATE osf_basefilenode
        SET node_id = target_object_id;
        """]
        ),
    ]

from __future__ import unicode_literals

from django.db import migrations, models, connection
from django.contrib.contenttypes.models import ContentType


def set_basefilenode_target(apps, schema_editor):
    BaseFileNode = apps.get_model('osf', 'basefilenode')
    AbstractNode = apps.get_model('osf', 'abstractnode')
    target_content_type_id = ContentType.objects.get_for_model(AbstractNode).id

    BATCHSIZE = 5000

    max_pk = BaseFileNode.objects.aggregate(models.Max('pk'))['pk__max']
    if max_pk is not None:
        for offset in range(0, max_pk + 1, BATCHSIZE):
            (BaseFileNode.objects
                .filter(pk__gte=offset)
                .filter(pk__lt=offset + BATCHSIZE)
                .filter(target_object_id__isnull=True)
                .filter(target_content_type_id__isnull=True)
                .update(
                    target_content_type_id=target_content_type_id,
                    target_object_id=models.F('node_id')
                )
            )


def reset_basefilenode_target_to_node(*args, **kwargs):
    sql = "UPDATE osf_basefilenode SET node_id = target_object_id;"
    with connection.cursor() as cursor:
        cursor.execute(sql)

class Migration(migrations.Migration):

    # Avoid locking basefilenode
    atomic = False

    dependencies = [
        ('osf', '0083_add_file_fields_for_target'),
    ]

    operations = [
        migrations.RunPython(set_basefilenode_target, reset_basefilenode_target_to_node),
    ]

Use batches instead of raw sql for long migration
Use batches instead of raw sql for long migration

  from __future__ import unicode_literals
  
- from django.db import migrations
+ from django.db import migrations, models, connection
+ from django.contrib.contenttypes.models import ContentType
  
  
+ def set_basefilenode_target(apps, schema_editor):
+     BaseFileNode = apps.get_model('osf', 'basefilenode')
+     AbstractNode = apps.get_model('osf', 'abstractnode')
+     target_content_type_id = ContentType.objects.get_for_model(AbstractNode).id
+ 
+     BATCHSIZE = 5000
+ 
+     max_pk = BaseFileNode.objects.aggregate(models.Max('pk'))['pk__max']
+     if max_pk is not None:
+         for offset in range(0, max_pk + 1, BATCHSIZE):
+             (BaseFileNode.objects
+                 .filter(pk__gte=offset)
+                 .filter(pk__lt=offset + BATCHSIZE)
+                 .filter(target_object_id__isnull=True)
+                 .filter(target_content_type_id__isnull=True)
+                 .update(
+                     target_content_type_id=target_content_type_id,
+                     target_object_id=models.F('node_id')
+                 )
+             )
+ 
+ 
+ def reset_basefilenode_target_to_node(*args, **kwargs):
+     sql = "UPDATE osf_basefilenode SET node_id = target_object_id;"
+     with connection.cursor() as cursor:
+         cursor.execute(sql)
+ 
  class Migration(migrations.Migration):
+ 
+     # Avoid locking basefilenode
+     atomic = False
  
      dependencies = [
          ('osf', '0083_add_file_fields_for_target'),
      ]
  
      operations = [
+         migrations.RunPython(set_basefilenode_target, reset_basefilenode_target_to_node),
-         migrations.RunSQL(
-             ["""
-         UPDATE osf_basefilenode
-         SET target_object_id = node_id;
-         UPDATE osf_basefilenode
-         SET target_content_type_id = (SELECT id FROM django_content_type WHERE app_label = 'osf' AND model = 'abstractnode');
-         """], ["""
-         UPDATE osf_basefilenode
-         SET node_id = target_object_id;
-         """]
-         ),
      ]
  
Use batches instead of raw sql for long migration
## Code Before:
from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('osf', '0083_add_file_fields_for_target'),
    ]

    operations = [
        migrations.RunSQL(
            ["""
        UPDATE osf_basefilenode
        SET target_object_id = node_id;
        UPDATE osf_basefilenode
        SET target_content_type_id = (SELECT id FROM django_content_type WHERE app_label = 'osf' AND model = 'abstractnode');
        """], ["""
        UPDATE osf_basefilenode
        SET node_id = target_object_id;
        """]
        ),
    ]

## Instruction:
Use batches instead of raw sql for long migration
## Code After:
from __future__ import unicode_literals

from django.db import migrations, models, connection
from django.contrib.contenttypes.models import ContentType


def set_basefilenode_target(apps, schema_editor):
    BaseFileNode = apps.get_model('osf', 'basefilenode')
    AbstractNode = apps.get_model('osf', 'abstractnode')
    target_content_type_id = ContentType.objects.get_for_model(AbstractNode).id

    BATCHSIZE = 5000

    max_pk = BaseFileNode.objects.aggregate(models.Max('pk'))['pk__max']
    if max_pk is not None:
        for offset in range(0, max_pk + 1, BATCHSIZE):
            (BaseFileNode.objects
                .filter(pk__gte=offset)
                .filter(pk__lt=offset + BATCHSIZE)
                .filter(target_object_id__isnull=True)
                .filter(target_content_type_id__isnull=True)
                .update(
                    target_content_type_id=target_content_type_id,
                    target_object_id=models.F('node_id')
                )
            )


def reset_basefilenode_target_to_node(*args, **kwargs):
    sql = "UPDATE osf_basefilenode SET node_id = target_object_id;"
    with connection.cursor() as cursor:
        cursor.execute(sql)

class Migration(migrations.Migration):

    # Avoid locking basefilenode
    atomic = False

    dependencies = [
        ('osf', '0083_add_file_fields_for_target'),
    ]

    operations = [
        migrations.RunPython(set_basefilenode_target, reset_basefilenode_target_to_node),
    ]
