Как я могу использовать UUID в SQLAlchemy?

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

65
задан Basil Bourque 13 November 2013 в 07:50
поделиться

2 ответа

Вы могли попытаться писать пользовательский тип , например:

import sqlalchemy.types as types

class UUID(types.TypeEngine):
    def get_col_spec(self):
        return "uuid"

    def bind_processor(self, dialect):
        def process(value):
            return value
        return process

    def result_processor(self, dialect):
        def process(value):
            return value
        return process

table = Table('foo', meta,
    Column('id', UUID(), primary_key=True),
)
-18
ответ дан Florian Bösch 24 November 2019 в 15:13
поделиться

Я написал это , и домен исчез, но вот смелость ...

Независимо от того, как мои коллеги, которые действительно заботятся о правильном дизайне базы данных, относятся к используемым UUID и GUID, использовали для ключевых полей. Я часто нахожу, что мне нужно это сделать. Я думаю, что он имеет некоторые преимущества по сравнению с автоинкрементом, которые стоят того.

Я уточнял тип столбца UUID в течение последних нескольких месяцев, и я думаю, что наконец-то получил его.

from sqlalchemy import types
from sqlalchemy.dialects.mysql.base import MSBinary
from sqlalchemy.schema import Column
import uuid


class UUID(types.TypeDecorator):
    impl = MSBinary
    def __init__(self):
        self.impl.length = 16
        types.TypeDecorator.__init__(self,length=self.impl.length)

    def process_bind_param(self,value,dialect=None):
        if value and isinstance(value,uuid.UUID):
            return value.bytes
        elif value and not isinstance(value,uuid.UUID):
            raise ValueError,'value %s is not a valid uuid.UUID' % value
        else:
            return None

    def process_result_value(self,value,dialect=None):
        if value:
            return uuid.UUID(bytes=value)
        else:
            return None

    def is_mutable(self):
        return False


id_column_name = "id"

def id_column():
    import uuid
    return Column(id_column_name,UUID(),primary_key=True,default=uuid.uuid4)

# Usage
my_table = Table('test',
         metadata,
         id_column(),
         Column('parent_id',
            UUID(),
            ForeignKey(table_parent.c.id)))

Я считаю, что хранение в двоичном виде (16 байт) должно в конечном итоге оказаться более эффективным, чем строковое представление. (36 байт?), И, кажется, есть некоторое указание на то, что индексирование 16-байтовых блоков должно быть более эффективным в mysql, чем строки. В любом случае, я бы не ожидал, что это будет хуже.

Один из недостатков, которые я обнаружил, заключается в том, что по крайней мере в phpymyadmin вы можете t редактировать записи, потому что он неявно пытается выполнить какое-то преобразование символов для «select * from table, где id = ...» и возникают различные проблемы с отображением.

Кроме этого, все вроде бы работает нормально, и поэтому я ' Я бросаю это там. Оставьте комментарий, если вы видите явную ошибку с ним. Я приветствую любые предложения по его улучшению.

Если не пропущено что-то, вышеуказанное решение будет работать, если базовая база данных имеет тип UUID. Если этого не произойдет, вы, скорее всего, получите ошибки при создании таблицы. Решение, которое я придумал, изначально предназначалось для MSSqlServer, а затем, в конце концов, перешло на MySql, так что я думаю, что мое решение немного более гибкое, так как кажется, что оно отлично работает на mysql и sqlite. Еще не потрудились проверить postgres.

Оставьте комментарий, если вы видите явную ошибку с ним. Я приветствую любые предложения по его улучшению.

Если не пропущено что-то, вышеуказанное решение будет работать, если базовая база данных имеет тип UUID. Если этого не произойдет, вы, скорее всего, получите ошибки при создании таблицы. Решение, которое я придумал, изначально предназначалось для MSSqlServer, а затем, в конце концов, перешло на MySql, так что я думаю, что мое решение немного более гибкое, так как кажется, что оно отлично работает на mysql и sqlite. Еще не потрудились проверить postgres.

Оставьте комментарий, если вы видите явную ошибку с ним. Я приветствую любые предложения по его улучшению.

Если не пропущено что-то, вышеуказанное решение будет работать, если базовая база данных имеет тип UUID. Если этого не произойдет, вы, скорее всего, получите ошибки при создании таблицы. Решение, которое я придумал, изначально предназначалось для MSSqlServer, а затем, в конце концов, перешло на MySql, так что я думаю, что мое решение немного более гибкое, так как кажется, что оно отлично работает на mysql и sqlite. Еще не потрудились проверить postgres.

Решение, которое я придумал, изначально предназначалось для MSSqlServer, а затем, в конце концов, перешло на MySql, так что я думаю, что мое решение немного более гибкое, так как кажется, что оно отлично работает на mysql и sqlite. Еще не потрудились проверить postgres.

Решение, которое я придумал, изначально предназначалось для MSSqlServer, а затем, в конце концов, перешло на MySql, так что я думаю, что мое решение немного более гибкое, так как кажется, что оно отлично работает на mysql и sqlite. Еще не потрудились проверить postgres.

62
ответ дан 24 November 2019 в 15:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: