# Generated by Django 3.2.13 on 2022-05-02 11:06

from django.db import migrations
from django.db.models import F
import uuid
import datetime
import pytz

BATCH_SIZE = 10000


def set_order_discount_token_and_created_at(apps, _schema_editor):
    OrderDiscount = apps.get_model("discount", "OrderDiscount")
    Order = apps.get_model("order", "Order")

    queryset = OrderDiscount.objects.filter(token__isnull=True)
    for batch_pks in queryset_in_batches(queryset):
        discounts = OrderDiscount.objects.filter(pk__in=batch_pks)
        order_in_bulk = Order.objects.in_bulk(
            discounts.values_list("order_id", flat=True)
        )
        for discount in discounts:
            order = order_in_bulk.get(discount.order_id)
            discount.created_at = (
                order.created_at if order else datetime.datetime.now(pytz.UTC)
            )
            discount.token = uuid.uuid4()

        OrderDiscount.objects.bulk_update(discounts, ["token", "created_at"])


def queryset_in_batches(queryset):
    """Slice a queryset into batches.

    Input queryset should be sorted be pk.
    """
    start_pk = 0

    while True:
        qs = queryset.order_by("pk").filter(pk__gt=start_pk)[:BATCH_SIZE]
        pks = list(qs.values_list("pk", flat=True))

        if not pks:
            break

        yield pks

        start_pk = pks[-1]


def set_order_discount_old_id(apps, schema_editor):
    OrderDiscount = apps.get_model("discount", "OrderDiscount")
    OrderDiscount.objects.all().update(old_id=F("id"))


class Migration(migrations.Migration):

    dependencies = [
        ("discount", "0040_orderdiscount_token_old_id_created_at"),
    ]

    operations = [
        migrations.RunPython(
            set_order_discount_token_and_created_at,
            migrations.RunPython.noop,
        ),
        migrations.RunPython(
            set_order_discount_old_id, reverse_code=migrations.RunPython.noop
        ),
    ]

# Generated by Django 3.2.13 on 2022-05-02 11:06
import datetime
import pytz

from django.db import migrations
from django.db.models import F, OuterRef, Subquery
from django.contrib.postgres.functions import RandomUUID
from django.contrib.postgres.operations import CryptoExtension
from django.db.models.functions import Coalesce


def set_order_discount_token_and_created_at(apps, _schema_editor):
    OrderDiscount = apps.get_model("discount", "OrderDiscount")
    Order = apps.get_model("order", "Order")

    OrderDiscount.objects.filter(token__isnull=True).update(
        token=RandomUUID(),
        created_at=Coalesce(
            Subquery(
                Order.objects.filter(discounts=OuterRef("id")).values("created_at")[:1]
            ),
            datetime.datetime.now(pytz.UTC),
        ),
    )


def set_order_discount_old_id(apps, schema_editor):
    OrderDiscount = apps.get_model("discount", "OrderDiscount")
    OrderDiscount.objects.all().update(old_id=F("id"))


class Migration(migrations.Migration):

    dependencies = [
        ("discount", "0040_orderdiscount_token_old_id_created_at"),
    ]

    operations = [
        CryptoExtension(),
        migrations.RunPython(
            set_order_discount_token_and_created_at,
            migrations.RunPython.noop,
        ),
        migrations.RunPython(
            set_order_discount_old_id, reverse_code=migrations.RunPython.noop
        ),
    ]

Optimize 0041_fulfill_orderdiscount_token_created_at_old_id migration (#10009)