Django ORM 能否以与后端无关的可靠方式存储无符号 64 位整数(又名 ulong64 或 uint64)?

问题描述 投票:0回答:2

我见过的所有文档都暗示您可能能够做到这一点,但没有任何官方 w/r/t ulong64/uint64 字段。在这个领域有一些现成的选项看起来很有前途:

  • BigIntegerField
    ...几乎,但签名;
  • PositiveIntegerField
    ... 看起来可疑的 32 位;和
  • DecimalField
    ...根据
    the docs
    ,用 python decimal 类型表示的固定指针——当被存放起来时,它大概会变成一个类似迂腐且缓慢的数据库字段,就像 DECIMAL 或 NUMERIC PostgreSQL 一样类型。

...所有这些看起来就像它们可能存储这样的数字。除了他们都不会承诺,就像休·格兰特扮演的每一个浪漫喜剧角色一样。

我的主要标准是它可以与 Django 支持的后端配合使用,没有任何

if postgresql (...) elif mysql (...)
类型的特殊情况废话。之后,需要速度 - 这是视觉数据库应用程序中的模型字段,它将索引图像派生数据(例如感知哈希和提取的关键点特征),允许按这些图像的内容进行排序和分组.

那么:有没有一个好的 Django 扩展或应用程序可以提供某种适合我的目的的

PositiveBigIntegerField

并且,除此之外:如果有一种简单可靠的方法来使用 Django 的普通 ORM 来存储无符号 64 位整数,我想知道它。看,我不是二进制高手;我必须在纸上进行补码——因此,如果您的这种方法涉及一些位移位技巧,请毫不犹豫地解释它是什么,即使它让您觉得很明显。预先感谢。

python django orm django-models unsigned-long-long-int
2个回答
26
投票

虽然我没有测试它,但你可能希望只是子类化

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()
返回的值,并且存储列类型的定义,例如。 here 如果是 MySQL 后端并确定here。看起来覆盖
db_type()
可以让您控制字段在数据库中的表示方式。但是,您需要通过检查
db_type()
参数找到一种方法来返回
connection
中特定于 DBMS 的值。


0
投票

BigAutoField 似乎足以存储 64 位无符号整数,尽管它需要是实例的主键。

参见文档

© www.soinside.com 2019 - 2024. All rights reserved.