Peewee + MySQL, How to create a custom field type that wraps SQL inline attachments?

I would like to create a custom UUID field in peewee (via MySQL).

In python, I use UUID as a hexadecimal string, for example:

uuid = '110e8400-e29b-11d4-a716-446655440000'

But I want to save it in the database in the type column in BINARY(16)order to save space.

MySQL has a built-in methods HEX()and UNHEX()for converting between string and binary code.

So my question is, how can I say that peewee generates SQL that uses an inline function? Here is the idea for the code I want to work:

class UUIDField(Field):
    db_field='binary(16)'

    def db_value(self, value):
        if value is not None:
            uuid = value.translate(None, '-')   # remove dashes
            # HERE: How do I let peewee know I want to generate
            # a SQL string of the form "UNHEX(uuid)"?

    def python_value(self, value):
        if value is not None:
            # HERE: How do I let peewee know I want to generate
            # a SQL string of the form "HEX(value)"?

, , peewee SQL. , , , python, SQL.

EDIT: , , python. , , !

import binascii
from peewee import *

db = MySQLDatabase(
    'database',
    fields={'binary(16)': 'BINARY(16)'}     # map the field type
)

# this does the uuid conversion in python
class UUIDField(Field):
    db_field='binary(16)'

    def db_value(self, value):
        if value is None: return None

        value = value.translate(None, '-')
        value = binascii.unhexlify(value)

        return value

    def python_value(self, value):
        if value is None: return None

        value = '{}-{}-{}-{}-{}'.format(
            binascii.hexlify(value[0:4]),
            binascii.hexlify(value[4:6]),
            binascii.hexlify(value[6:8]),
            binascii.hexlify(value[8:10]),
            binascii.hexlify(value[10:16])
        )

        return value
+4
1

SelectQuery, SQL- :

from peewee import SelectQuery

# this does the uuid conversion in python
class UUIDField(Field):
    db_field = 'binary(16)'

    def db_value(self, value):
        if value is None: return None

        value = value.translate(None, '-')
        query = SelectQuery(self.model_class, fn.UNHEX(value).alias('unhex'))
        result = query.first()
        value = result.unhex
        return value

    def python_value(self, value):
        if value is None: return None
        query = SelectQuery(self.model_class, fn.HEX(value).alias('hex'))
        result = query.first()
        value = '{}-{}-{}-{}-{}'.format(
            result.hex[0:8],
            result.hex[8:12],
            result.hex[12:16],
            result.hex[16:20],
            result.hex[20:32]
        )
        return value
+2

Source: https://habr.com/ru/post/1605842/


All Articles