Skip to content

Commit

Permalink
ref: move changes to tortoise/contrib/mysql/fields.py
Browse files Browse the repository at this point in the history
  • Loading branch information
plusiv committed Aug 22, 2023
1 parent feba9d7 commit c946b60
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 20 deletions.
49 changes: 49 additions & 0 deletions tortoise/contrib/mysql/fields.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,54 @@
from tortoise.fields import Field
from tortoise.fields.data import UUIDField as UUIDFieldBase
from uuid import UUID, uuid4
from typing import Any, Optional, Type, Union, TYPE_CHECKING

if TYPE_CHECKING: # pragma: nocoverage
from tortoise.models import Model


class GeometryField(Field):
SQL_TYPE = "GEOMETRY"

class UUIDField(UUIDFieldBase[Union[UUID, bytes]], Union[UUID, bytes]):
"""
UUID Field
This field can store uuid value, but with the option to add binary compression.
If used as a primary key, it will auto-generate a UUID4 by default.
``binary_compression``: (bool)
If True, the UUID will be stored in binary format.
This will save 6 bytes per UUID in the database.
Note: that this is a MySQL-only feature.
See https://dev.mysql.com/blog-archive/mysql-8-0-uuid-support/ for more details.
"""

SQL_TYPE = "CHAR(36)"

def __init__(self, binary_compression: bool = True, **kwargs: Any) -> None:
if kwargs.get("pk", False) and "default" not in kwargs:
kwargs["default"] = uuid4
super().__init__(**kwargs)

if binary_compression:
self.SQL_TYPE = "BINARY(16)"
self._binary_compression = binary_compression

def to_db_value(self, value: Any) -> Optional[Union[str, bytes]]:
# Make sure that value is a UUIDv4
# If not, raise an error
# This is to prevent UUIDv1 or any other version from being stored in the database
if self._binary_compression and isinstance(value, UUID):
return value.bytes
return value and str(value)

def to_python_value(self, value: Any) -> Optional[Union[UUID, bytes]]:
if value is None or isinstance(value, UUID):
# Convert to UUID if binary_compression is True
# and value is bytes Type
if self._binary_compression and isinstance(value, bytes):
return UUID(bytes=bytes(value))
return value
return UUID(value)
22 changes: 2 additions & 20 deletions tortoise/fields/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,41 +605,23 @@ class UUIDField(Field[UUID], UUID):
This field can store uuid value.
If used as a primary key, it will auto-generate a UUID4 by default.
``binary_compression``: (bool)
If True, the UUID will be stored in binary format.
This will save 6 bytes per UUID in the database.
Note: that this is a MySQL-only feature. See https://dev.mysql.com/blog-archive/mysql-8-0-uuid-support/ for more details.
"""

SQL_TYPE = "CHAR(36)"

class _db_mysql:
SQL_TYPE = "CHAR(36)"

class _db_postgres:
SQL_TYPE = "UUID"

def __init__(self, binary_compression: bool = False, **kwargs: Any) -> None:
def __init__(self, **kwargs: Any) -> None:
if kwargs.get("pk", False) and "default" not in kwargs:
kwargs["default"] = uuid4
super().__init__(**kwargs)

if binary_compression:
self._db_mysql.SQL_TYPE = "BINARY(16)"
self._binary_compression = binary_compression

def to_db_value(self, value: Any, instance: "Union[Type[Model], Model]") -> Optional[Union[str, bytes]]:
# Convert to UUID if binary_compression is True
if self._binary_compression:
return value.bytes.hex()
def to_db_value(self, value: Any, instance: "Union[Type[Model], Model]") -> Optional[str]:
return value and str(value)

def to_python_value(self, value: Any) -> Optional[UUID]:
if value is None or isinstance(value, UUID):
# Convert to UUID if binary_compression is True
if self._binary_compression and isinstance(value, bytes):
return UUID(bytes=bytes.fromhex(value))
return value
return UUID(value)

Expand Down

0 comments on commit c946b60

Please sign in to comment.