Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate order line id from int to UUID #9637

Merged
merged 12 commits into from
May 10, 2022
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
All notable, unreleased changes to this project will be documented in this file. For the released changes, please visit the [Releases](https://github.com/mirumee/saleor/releases) page.

# Unreleased
- Migrate order line id from int to UUID - #9637 by @IKarbowiak
- Changed the order line `id` from `int` to `UUID`, the old ids still can be used
for old order lines.
- Fix invalid `ADDED_PRODUCTS` event parameter for `OrderLinesCreate` mutation - #9653 by @IKarbowiak

### Other changes
Expand Down
3 changes: 2 additions & 1 deletion saleor/graphql/account/types.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import uuid
from typing import List

import graphene
Expand Down Expand Up @@ -197,7 +198,7 @@ def resolve_count(root: models.CustomerEvent, _info):
def resolve_order_line(root: models.CustomerEvent, info):
if "order_line_pk" in root.parameters:
return OrderLineByIdLoader(info.context).load(
root.parameters["order_line_pk"]
uuid.UUID(root.parameters["order_line_pk"])
)
return None

Expand Down
36 changes: 20 additions & 16 deletions saleor/graphql/core/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@
)
from ..utils import get_nodes, resolve_global_ids_to_primary_keys
from .descriptions import DEPRECATED_IN_3X_FIELD
from .types import File, NonNullList, Upload, UploadError
from .types import (
TYPES_WITH_DOUBLE_ID_AVAILABLE,
File,
NonNullList,
Upload,
UploadError,
)
from .utils import from_global_id_or_error, snake_to_camel_case
from .utils.error_codes import get_error_code_from_error

Expand Down Expand Up @@ -177,26 +183,24 @@ def _get_node_by_pk(
Whether by using the provided query set object or by calling type's get_node().
"""
if qs is not None:
if str(graphene_type) == "Order":
return cls._get_order_node_by_pk(pk, qs)
return qs.filter(pk=pk).first()
lookup = Q(pk=pk)
if pk is not None and str(graphene_type) in TYPES_WITH_DOUBLE_ID_AVAILABLE:
# This is temporary solution that allows fetching objects with use of
# new and old id.
try:
UUID(str(pk))
except ValueError:
lookup = (
Q(number=pk) & Q(use_old_id=True)
if str(graphene_type) == "Order"
else Q(old_id=pk) & Q(old_id__isnull=False)
)
return qs.filter(lookup).first()
get_node = getattr(graphene_type, "get_node", None)
if get_node:
return get_node(info, pk)
return None

@classmethod
def _get_order_node_by_pk(cls, pk: Union[int, str], qs):
# This is temporary method that allows fetching orders with use of
# new and old id.
lookup = Q(pk=pk)
if pk is not None:
try:
UUID(str(pk))
except ValueError:
lookup = Q(number=pk) & Q(use_old_id=True)
return qs.filter(lookup).first()

@classmethod
def get_global_id_or_error(
cls, id: str, only_type: Union[ObjectType, str] = None, field: str = "id"
Expand Down
1 change: 1 addition & 0 deletions saleor/graphql/core/types/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# flake8: noqa
from .common import (
TYPES_WITH_DOUBLE_ID_AVAILABLE,
AccountError,
AppError,
AttributeError,
Expand Down
4 changes: 4 additions & 0 deletions saleor/graphql/core/types/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
from ..scalars import PositiveDecimal
from .money import VAT

# deprecated - this is temporary constant that contains the graphql types
# which has double id available - uuid and old int id
TYPES_WITH_DOUBLE_ID_AVAILABLE = ["Order", "OrderLine"]


class NonNullList(graphene.List):
"""A list type that automatically adds non-null constraint on contained items."""
Expand Down
29 changes: 15 additions & 14 deletions saleor/graphql/core/types/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from django.db.models import Model, Q
from graphene.types.objecttype import ObjectType, ObjectTypeOptions

from . import TYPES_WITH_DOUBLE_ID_AVAILABLE


class ModelObjectOptions(ObjectTypeOptions):
model = None
Expand Down Expand Up @@ -46,24 +48,23 @@ def __init_subclass_with_meta__(
@classmethod
def get_node(cls, _, id):
model = cls._meta.model
try:
if cls._meta.name == "Order":
return cls._get_order(id, model)
return model.objects.get(pk=id)
except model.DoesNotExist:
return None

@classmethod
def _get_order(cls, id, model):
# This is temporary method that allows fetching orders with use of
# new (uuid type) and old (int type) id
type_name = cls._meta.name
lookup = Q(pk=id)
if id is not None:
if id is not None and type_name in TYPES_WITH_DOUBLE_ID_AVAILABLE:
# This is temporary solution that allows fetching orders with use of
# new (uuid type) and old (int type) id
try:
UUID(str(id))
except ValueError:
lookup = Q(number=id) & Q(use_old_id=True)
return model.objects.get(lookup)
lookup = (
Q(number=id) & Q(use_old_id=True)
if type_name == "Order"
else Q(old_id=id) & Q(old_id__isnull=False)
)
try:
return model.objects.get(lookup)
except model.DoesNotExist:
return None

@classmethod
def get_model(cls):
Expand Down
2 changes: 1 addition & 1 deletion saleor/graphql/order/dataloaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def batch_load(self, keys):
lines = (
OrderLine.objects.using(self.database_connection_name)
.filter(order_id__in=keys)
.order_by("pk")
.order_by("created_at")
)
line_map = defaultdict(list)
for line in lines.iterator():
Expand Down