2012-05-20 6 views
25

Tutti i documenti che ho visto implicano che si può essere in grado di farlo, ma non c'è nulla di ufficiale w/r/t ulong64/uint64 campi. Ci sono alcune opzioni disponibili che sembrano abbastanza promettenti in questa arena:Può l'ORM di Django archiviare un numero intero a 64 bit senza segno (pseudonimo di ulong64 o uint64) in modo affidabile e senza back-end?

  • BigIntegerField ... quasi, ma firmato;
  • PositiveIntegerField ... sospettosamente a 32 bit; e
  • DecimalField ... un puntatore fisso rappresentato con un tipo pitone decimal, secondo the docs - che si trasforma presumibilmente in un campo di database analogamente pedante e lento quando socked via, à la decimale o tipi numerici PostgreSQL.

... ognuno dei quali sembrano come hanno potrebbero memorizzare un numero del genere. Tranne che NON NESSUNO DI LORO SI IMPEGNERO, proprio come ogni singolo personaggio rom interpretato da Hugh Grant.

Il mio criterio principale è che funzioni con i backend supportati da Django, senza alcun tipo di assurdità da caso speciale if postgresql (...) elif mysql (...). Dopodiché, c'è bisogno di velocità - questo è per un campo modello in un'applicazione visual-database che indicizzerà i dati derivati ​​da immagini (es. Hash percettivi e feature per punti chiave estratti), permettendo l'ordinamento e il raggruppamento in base al contenuto di tali immagini .

Quindi: c'è una buona estensione o app Django che fornisce una specie di che soddisferà i miei scopi?

E, a meno che: se esiste un modo semplice e affidabile per utilizzare l'ORM di Django per archiviare gli input a 64 bit senza segno, mi piacerebbe saperlo. Guarda, non sono un mago binario; Devo fare il complemento a due su carta - quindi se questo tuo metodo comporta qualche piccolo inganno, non esitare a spiegare di cosa si tratta, anche se ti sembra ovvio. Grazie in anticipo.

+5

+1 per "molto simile a ogni singolo personaggio di Rom-com interpretato da Hugh Grant" mi ha fatto ridacchiare in una mattina triste e umida. –

risposta

17

Anche se non l'ho provato, si potrebbe desiderare semplicemente la sottoclasse BigIntegerField. L'originale BigIntegerField sembra che (source here):

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) 

Derivato PositiveBigIntegerField maggio si presenta così:

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) 

Anche se si dovrebbe provare a fondo, prima di utilizzarlo. Se lo fai, si prega di condividere i risultati :)

EDIT:

ho perso una cosa - la rappresentazione database interno. Questo si basa sul valore restituito da get_internal_type() e la definizione del tipo di colonna è memorizzata ad es. here in caso di backend MySQL e determinato here. Sembra che la sovrascrittura db_type() ti dia il controllo su come il campo è rappresentato nel database. Tuttavia, sarà necessario trovare un modo per restituire il valore specifico DBMS in db_type() selezionando l'argomento connection.

+1

Wow, sembra troppo bello per essere vero, per così dire - Non sono troppo preoccupato di convalidare l'input umano tramite 'FormField' (dato che questo dato proviene da una funzione di analisi dell'immagine) e se prendi quella roba, ci rimane il testo 'description', l'attributo' MAX_BIGINT' e la specifica 'get_internal_type' ... che nessuna di queste aggiunte lascia che la sottoclasse dica all'ORM come trattarla come un uint64. Potrei sbagliarmi molto - se mi manca qualcosa qui con uno di questi, fammi sapere. – fish2000

+1

@ fish2000: avevi ragione, vedi la mia modifica. La parte che mi mancava era 'db_field()' che intendeva restituire il tipo specifico di DBMS basato sul tipo interno restituito da 'get_internal_type()' e cercato nel dizionario 'data_types' specifico per DBMS (visto [qui] (https: //github.com/django/django/blob/master/django/db/backends/mysql/creation.py#L8)). Risolve il tuo problema ora? – Tadeck

+0

Bello! È bello sapere dove l'ORM ripone il proprio mucchio di frammenti SQL di case-edge proprietario - non l'avevo mai incontrato prima ed è quello che serve per implementare i metodi 'get_internal_type()' con la stessa logica specifica del fornitore di Django si. È un ottimo consiglio, grazie! – fish2000

Problemi correlati