Skip to content

Commit d06d941

Browse files
committed
fixing some edge cases for UUID column defaults, when using migrations
1 parent 76cb13b commit d06d941

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

piccolo/apps/migrations/auto/serialisation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def __eq__(self, other):
149149
return self.__hash__() == other.__hash__()
150150

151151
def __repr__(self):
152-
return f"UUID({str(self.instance)})"
152+
return f"UUID('{str(self.instance)}')"
153153

154154

155155
###############################################################################

piccolo/columns/base.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from enum import Enum
88
import inspect
99
import typing as t
10+
import uuid
1011

1112
from piccolo.columns.operators.comparison import (
1213
ComparisonOperator,
@@ -342,6 +343,7 @@ def _validate_default(
342343
self,
343344
default: t.Any,
344345
allowed_types: t.Iterable[t.Union[None, t.Type[t.Any]]],
346+
allow_recursion: bool = True,
345347
) -> bool:
346348
"""
347349
Make sure that the default value is of the allowed types.
@@ -357,9 +359,14 @@ def _validate_default(
357359
):
358360
self._validated = True
359361
return True
360-
elif callable(default):
361-
self._validated = True
362-
return True
362+
elif inspect.isfunction(default):
363+
# We need to prevent recursion, otherwise a function which returns
364+
# a function would be an infinite loop.
365+
if allow_recursion and self._validate_default(
366+
default(), allowed_types=allowed_types, allow_recursion=False
367+
):
368+
self._validated = True
369+
return True
363370
elif (
364371
isinstance(default, Enum) and type(default.value) in allowed_types
365372
):
@@ -536,6 +543,8 @@ def get_sql_value(self, value: t.Any) -> t.Any:
536543
output = f"'{value.isoformat().replace('T', '')}'"
537544
elif isinstance(value, bytes):
538545
output = f"'{value.hex()}'"
546+
elif isinstance(value, uuid.UUID):
547+
output = f"'{value}'"
539548
elif isinstance(value, list):
540549
# Convert to the array syntax.
541550
output = (

piccolo/columns/column_types.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,23 @@ class Band(Table):
303303
value_type = uuid.UUID
304304

305305
def __init__(self, default: UUIDArg = UUID4(), **kwargs) -> None:
306+
if default is UUID4:
307+
# In case the class is passed in, instead of an instance.
308+
default = UUID4()
309+
306310
self._validate_default(default, UUIDArg.__args__) # type: ignore
307311

308312
if default == uuid.uuid4:
309313
default = UUID4()
310314

315+
if isinstance(default, str):
316+
try:
317+
default = uuid.UUID(default)
318+
except ValueError:
319+
raise ValueError(
320+
"The default is a string, but not a valid uuid."
321+
)
322+
311323
self.default = default
312324
kwargs.update({"default": default})
313325
super().__init__(**kwargs)

piccolo/columns/defaults/uuid.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def python(self):
1818
return uuid.uuid4()
1919

2020

21-
UUIDArg = t.Union[UUID4, uuid.UUID, Enum, None]
21+
UUIDArg = t.Union[UUID4, uuid.UUID, str, Enum, None]
2222

2323

2424
__all__ = ["UUIDArg", "UUID4"]

tests/apps/migrations/auto/integration/test_migrations.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ def integer_default():
3232
return 1
3333

3434

35+
def uuid_default():
36+
return uuid.uuid4()
37+
38+
3539
@postgres_only
3640
class TestMigrations(TestCase):
3741
def tearDown(self):
@@ -139,18 +143,19 @@ def test_uuid_column(self):
139143
self.table(column)
140144
for column in [
141145
UUID(),
142-
# UUID(default="ecf338cd-6da7-464c-b31e-4b2e3e12f0f0"),
143-
# UUID(
144-
# default=uuid.UUID(
145-
# "2dfc9c47-adab-4692-b804-f692f3b0fc07"
146-
# )
147-
# ),
148-
# UUID(default=uuid.uuid4),
149-
# UUID(default=UUID4),
150-
# UUID(null=True),
151-
# UUID(null=False),
152-
# UUID(index=True),
153-
# UUID(index=False),
146+
UUID(default="ecf338cd-6da7-464c-b31e-4b2e3e12f0f0"),
147+
UUID(
148+
default=uuid.UUID(
149+
"2dfc9c47-adab-4692-b804-f692f3b0fc07"
150+
)
151+
),
152+
UUID(default=uuid.uuid4),
153+
UUID(default=uuid_default),
154+
UUID(default=UUID4()),
155+
UUID(null=True),
156+
UUID(null=False),
157+
UUID(index=True),
158+
UUID(index=False),
154159
]
155160
]
156161
)

0 commit comments

Comments
 (0)