Soru Django ORM, güvenilir olmayan bir arka-yanılma şeklinde imzasız bir 64-bit tam sayı (aka ulong64 veya uint64) saklayabilir mi?


Gördüğüm tüm dokümanlar, sizin belki Bunu yapabilir, ancak resmi w / r / t ulong64 / uint64 alanları yoktur. Bu alanda oldukça umut verici görünen birkaç hazır seçenekler var:

  • BigIntegerField ... neredeyse ama imzalı;
  • PositiveIntegerField ... şüpheli 32-bit görünümlü; ve
  • DecimalField ... bir python ile temsil edilen sabit bir işaretçi decimal türüne göre dokümanlar - muhtemelen uzaktayken benzer bir pedantic ve yavaş veritabanı alanına dönüşür, DECIMAL veya NUMERIC PostgreSQL türleri.

... hepsi de bak onlar gibi belki böyle bir sayıyı saklayın. Hugh Grant tarafından tasvir edilen her rom-com karakterine benzer.

Birincil ölçüt, Django'nun desteklediği arka planlar ile hiçbir şekilde çalışmadığıdır. if postgresql (...) elif mysql (...) Özel durum saçmalık tipi. Bundan sonra, hıza ihtiyaç var - bu, görsel-veri tabanı uygulamasında görüntüden türetilmiş verileri (örneğin algısal kareler ve çıkarılan kilit noktası özellikleri) indeksleyen, bu görüntülerin içeriğine göre sıralama ve gruplama sağlayan bir model alan içindir. .

Yani: iyi bir Django uzantısı ya da bir tür sağlar uygulama var mı PositiveBigIntegerField Bu benim amaçlarına uygun olacak mı?

Ve, bunu yasaklayan: Eğer imzasız 64-bit ints depolamak için Django'nun hisse senedi ORM kullanmak için basit ve güvenilir bir yolu varsa, bunu bilmek isterim. Bak, ben ikili vızıltı yok; İki tane tamamlayıcıyı kağıt üzerinde yapmalıyım - bu yüzden eğer bu metot biraz değişkenlik gösteren bir hile içeriyorsa, sizi açık bir şekilde vursa bile, ne olduğunu açıklamaktan çekinmeyin. Şimdiden teşekkürler.


27
2018-05-20 23:34


Menşei


İçin +1 much like every single rom-com character portrayed by Hugh Grant Beni kasvetli ve nemli bir sabahı kandırdı. - Burhan Khalid


Cevaplar:


Her ne kadar test etmedim, ama sadece alt sınıfta BigIntegerField. Orijinal BigIntegerField öyle görünüyor (buradan kaynak):

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)

Türetilmiş PositiveBigIntegerField şöyle görünebilir:

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)

Kullanmadan önce iyice test etmelisiniz. Eğer yaparsanız, lütfen sonuçları paylaşın :)

DÜZENLE:

Bir şeyi özledim - iç veritabanı temsili. Bu, tarafından döndürülen değere dayanır get_internal_type() ve kolon tipinin tanımı, örn. İşte MySQL backend durumunda ve belirlenir İşte. Üzerine yazıyormuş gibi görünüyor db_type() Alanın veritabanında nasıl temsil edildiğini kontrol edersiniz. Ancak, DBMS'ye özgü değeri döndürmek için bir yol bulmanız gerekecektir. db_type() kontrol ederek connection argüman.


20
2018-05-20 23:47



Vay, bu doğru olmak için çok iyi görünüyor, bu yüzden konuşmak - Ben insan girdisi yoluyla doğrulama konusunda çok endişelenmiyorum FormField (bu veri bir görüntü analizi fonksiyonundan gelecektir) ve eğer bu maddeleri çıkarırsanız, description metin MAX_BIGINT özniteliği ve get_internal_type Spesifikasyon ... bu eklemelerden hiçbiri, alt sınıfın ORM'ye nasıl bir uint64 gibi davranacağını söylemesine izin vermez. Yanılıyor olabilirim - eğer bunlardan herhangi biriyle eksik bir şey varsa, bana haber ver. - fish2000
@ fish2000: Haklıydın, düzenlememi görün. Kaybettiğim kısım db_field() Bu, tarafından döndürülen iç türüne göre DBMS'ye özgü tür döndürmek anlamına geliyordu. get_internal_type() ve DBMS'ye özel olarak baktı data_types sözlük (görüldü İşte). Şimdi sorununuzu çözüyor mu? - Tadeck
Güzel! ORM'nin kendi kendine özel SQL-Case SQL parçalarını sakladığını bilmek güzel bir şeydi - daha önce hiç rastlamamıştım. get_internal_type() Django'nun kendisi ile aynı satıcıya özgü mantığı olan yöntemler. Bu harika bir ipucu, teşekkürler! - fish2000
Görebildiğim kadarıyla db_field yöntem olmalı db_type (akran değerlendirmesinde bekleyen bir düzenleme yaptı). - Tikitu
Bu aynı zamanda SQLite için de çalışır, ancak gerçek saklanan değer bir imzalı 64bit INTEGER, bu yüzden izin verilen maksimum değer 2 ^ 63 - 1 olacak - Tzach