Подтвердить что ты не робот

Может ли Django ORM хранить неподписанное 64-битное целое число (aka ulong64 или uint64) в надежной бэкэндо-агностической манере?

Все документы, которые я видел, подразумевают, что вы можете это сделать, но нет никаких официальных полей w/r/t ulong64/uint64. Есть несколько готовых вариантов, которые выглядят довольно многообещающими на этой арене:

  • BigIntegerField... почти, но подписан;
  • PositiveIntegerField... подозрительно 32-битный; и
  • DecimalField... фиксированный указатель, представленный с типом python decimal, согласно docs - который, по-видимому, превращается в аналогичное педантичное и медленное поле базы данных при отсканировании, - типы DECIMAL или NUMERIC PostgreSQL.

... все из них выглядят так, будто они могут хранить такое число. Кроме того, что никто из них не будет COMMIT, так же, как каждый персонаж rom-com, изображенный Хью Грантом.

Мой основной критерий заключается в том, что он работает с поддерживаемыми Django бэкендами, без какого-либо типа t24 типа особой чепухи. После этого возникает потребность в скорости - это для поля модели в приложении визуальной базы данных, которое будет индексировать данные, полученные из изображений (например, перцептивные хэши и выделенные ключевые функции), позволяя упорядочивать и группировать содержимое этих изображений.

Итак: есть ли хорошее расширение Django или приложение, которое предоставляет какой-то PositiveBigIntegerField, который подойдет моим целям?

И, если это не так: если есть простой и надежный способ использования ORM Django для хранения 64-битных ints без знака, я хотел бы это знать. Слушай, я не бинарный свист; Я должен сделать два дополнения на бумаге, поэтому, если ваш метод связан с каким-то смехотворным обманом, не стесняйтесь объяснять, что это такое, даже если оно кажется вам очевидным. Спасибо заранее.

4b9b3361

Ответ 1

Хотя я не тестировал его, но вы можете просто подклассом 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.