2011-01-19 24 views
5

Utilizzo la base dichiarativa SQLAlchemy per definire il modello. Ho definito una proprietà name che viene calcolato da una delle colonne (title):SQLAlchemy: proprietà personalizzata della query basata sul campo della tabella

class Entry(Base): 
    __tablename__ = "blog_entry" 
    id = Column(Integer, primary_key=True) 
    title = Column(Unicode(255)) 
    ... 

    @property 
    def name(self): 
     return re.sub(r'[^a-zA-Z0-9 ]','',self.title).replace(' ','-').lower() 

Quando si tenta di eseguire una query utilizzando name, SQLAlchemy genera un errore:

Session.query(Entry).filter(Entry.name == my_name).first() 
>>> ArgumentError: filter() argument must be of type sqlalchemy.sql.ClauseElement or string 

Dopo aver esaminato per un po, Ho trovato che forse comparable_using() potrebbe aiutare, ma non ho trovato alcun esempio che mostri un comparatore che faccia riferimento a un'altra colonna della tabella.

È ancora possibile o esiste un approccio migliore?

risposta

5

Potete immaginare quale SQL dovrebbe essere emesso per la vostra richiesta? Il database non sa nulla di name, non ha né un modo per calcolarlo, né di usare alcun indice per accelerare la ricerca.

La mia migliore scommessa è una scansione completa, che recupera title per ogni record, calcolando name quindi da esso filtrato. Puoi farlo senza problemi con [x for x in Session.query(Entry).all() if x.name==my_name][0]. Con un po 'più di raffinatezza, recupererai solo id e title nella pass di filtraggio, quindi recupererai il/i record/i completo/i entro il id.

Si noti che una scansione completa di solito non è gradevole dal POV delle prestazioni, a meno che la tabella non sia abbastanza piccola.

+0

Grazie, ora vedo che devo provare un approccio diverso. – amercader

5

Da SQLAlchemy 0.7 è possibile raggiungere questo obiettivo usando hybrid_property vedere la documentazione qui: http://www.sqlalchemy.org/docs/orm/extensions/hybrid.html

+0

È possibile fornire un esempio di come utilizzare questo per eseguire una sostituzione di stringa come sopra? Sto ricevendo cose come TypeError: expected string o buffer' e 'AttributeError: Né l'oggetto 'InstrumentedAttribute' né l'oggetto 'Comparator' associato a Entry.page_title ha un attributo 'partition'' ma sto cercando di trattare i miei oggetti page_title come una stringa che posso vedere non è ... Non so come ottenere il valore della stringa però. – Katie

Problemi correlati