Может ли Django ORM хранить беззнаковое 64-битное целое число (также известное как ulong64 или uint64) надежным, независимым от серверной части способом?
-
12-12-2019 - |
Вопрос
Все документы, которые я видел, подразумевают, что вы мощь быть в состоянии это сделать, но нет ничего официального с полями ulong64/uint64.Есть несколько готовых вариантов, которые выглядят весьма многообещающе в этой области:
BigIntegerField
...почти, но подписано;PositiveIntegerField
...подозрительно 32-битный вид;иDecimalField
...фиксированный указатель, представленный Pythondecimal
тип, согласно документы -- которое, по-видимому, превращается в аналогично педантичное и медленное поле базы данных, когда его удаляют, а-ля типы DECIMAL или NUMERIC PostgreSQL.
...все из которых смотреть как они мощь сохраните такой номер.За исключением того, что НИ ОДИН ИЗ НИХ НЕ БУДЕТ СОВЕРШЕНСТВОВАТЬ, как и каждый персонаж ром-комов, которого изображает Хью Грант.
Мой главный критерий — чтобы он работал с поддерживаемыми Django серверами без каких-либо if postgresql (...) elif mysql (...)
типа частный случай ерунды.После этого возникает необходимость в скорости — это поле модели в приложении визуальной базы данных, которое будет индексировать данные, полученные из изображения (например,перцептивные хэши и извлеченные ключевые характеристики), позволяющие упорядочивать и группировать изображения по содержимому.
Так:есть ли хорошее расширение или приложение Django, которое предоставляет какой-то PositiveBigIntegerField
это подойдет для моих целей?
И, за исключением этого:Если есть простой и надежный способ использовать стандартную ORM Django для хранения беззнаковых 64-битных целых чисел, я бы хотел об этом знать.Послушайте, я не бинарный гений;Мне нужно составить дополнение до двух на бумаге, поэтому, если ваш метод включает в себя какой-то трюк со сдвигом битов, не стесняйтесь объяснить, что это такое, даже если он кажется вам очевидным.Заранее спасибо.
Решение
Хотя я это не проверял, но вы можете просто создать подкласс BigIntegerField
.Оригинал BigIntegerField
выглядит вот так(источник здесь):
class BigIntegerField(IntegerField):
empty_strings_allowed = False
description = _("Big (8 byte) integer")
MAX_BIGINT = 9223372036854775807
def get_internal_type(self):
return "BigIntegerField"
def formfield(self, **kwargs):
defaults = {'min_value': -BigIntegerField.MAX_BIGINT - 1,
'max_value': BigIntegerField.MAX_BIGINT}
defaults.update(kwargs)
return super(BigIntegerField, self).formfield(**defaults)
Полученный PositiveBigIntegerField
может выглядеть так:
class PositiveBigIntegerField(BigIntegerField):
empty_strings_allowed = False
description = _("Big (8 byte) positive integer")
def db_type(self, connection):
"""
Returns MySQL-specific column data type. Make additional checks
to support other backends.
"""
return 'bigint UNSIGNED'
def formfield(self, **kwargs):
defaults = {'min_value': 0,
'max_value': BigIntegerField.MAX_BIGINT * 2 - 1}
defaults.update(kwargs)
return super(PositiveBigIntegerField, self).formfield(**defaults)
Хотя перед использованием его следует тщательно протестировать.Если да, поделитесь результатами :)
РЕДАКТИРОВАТЬ:
Я упустил одну вещь — представление внутренней базы данных.Это основано на значении, возвращаемом get_internal_type()
и определение типа столбца сохраняется, например. здесь в случае серверной части MySQL и определено здесь.Это похоже на перезапись db_type()
даст вам контроль над тем, как поле будет представлено в базе данных.Однако вам нужно будет найти способ вернуть значение, специфичное для СУБД, в db_type()
проверив connection
аргумент.