2012-02-03 3 views
5

sto usando la ricetta SQLAlchemy here al magicamente JSON codifica/decodifica di una colonna dal DB nel mio modello come:SQLAlchemy colonna sinonimo con diversi tipi

class Thing(Base): 
    __tablename__ = 'things' 
    id = Column(Integer(), primary_key=True) 
    data = Column(JSONEncodedDict) 

mi ha colpito un intoppo quando ho voluto creare un in più campo "RAW_DATA" nel mio modello di accedere agli stessi dati JSON sottostanti, ma senza codifica/decodifica:

raw_data = Column("data", VARCHAR) 

SQLAlchemy sembra confondersi con il nome di collisione e lasciare una colonna non-mappata. Esiste un modo per convincere SQLAlchemy a mappare effettivamente entrambi gli attributi nella stessa colonna?

risposta

3

Definirei semplicemente la colonna raw_data tramite SQLAlchemy e quindi utilizzare la proprietà/setter di Python per rendere trasparente l'uso di data. I.e .:

class Thing(Base): 
    __tablename__ = 'things' 
    id = Column(Integer(), primary_key=True) 
    raw_data = Column(String()) 

    @property 
    def data(self): 
     # add some checking here too 
     return json.loads(self.raw_data) 

    @data.setter 
    def data(self, value): 
     # dito 
     self.raw_data = json.dumps(value) 
+0

Ci sono 2 problemi: 1) non gestisce correttamente le mutazioni sul posto, 2) JSON viene analizzato per ogni accesso di attributo. –

+0

@Denis: il tracciamento della mutazione sul posto è quasi ortogonale. Ho lavorato su di esso, e c'è molto di più rispetto a quanto suggerisce il documento: https://gist.github.com/1730610. –

+0

@DenisOtkidach, il secondo problema è facilmente risolvibile con il caching. È una specie di ottimizzazione prematura, quindi non l'ho incluso immediatamente. Non ho un sacco di esperienza con SQLAlchemy in particolare, ma da ciò che ho raccolto questa soluzione non è un approccio insolito. –