2015-04-23 10 views
6

C'è un modo per forzare un oggetto mappato da sqlalchemy per essere considerato dirty? Ad esempio, dato il contesto di sqlalchemy di Object Relational Tutorial il problema è dimostrata,forza l'oggetto è `sporco` in sqlalchemy

a=session.query(User).first() 
a.__dict__['name']='eh' 
session.dirty 

cedendo,

IdentitySet([]) 

Sto cercando un modo per forzare l'utente a in uno stato sporco.

Questo problema si verifica perché la classe mappata utilizzando sqlalchemy assume il controllo dei metodi getter/setter dell'attributo e impedisce a sqlalchemy di registrare le modifiche.

risposta

13

Mi sono imbattuto nello stesso problema di recente e non era ovvio.

Gli oggetti non sono sporchi, ma i loro attributi sono. Poiché SQLAlchemy scriverà solo gli attributi modificati, non l'intero oggetto, per quanto ne so.

Se si imposta un attributo utilizzando set_attribute ed è diverso dai dati degli attributi originali, SQLAlchemy fonda l'oggetto è sporco (TODO: ho bisogno di dettagli come lo fa il paragone):

from sqlalchemy.orm.attributes import set_attribute 
    set_attribute(obj, data_field_name, data) 

Se vuole marcare l'oggetto sporco indipendentemente dal valore dell'attributo originale, non importa se è cambiato o no, utilizzare flag_modified:

from sqlalchemy.orm.attributes import flag_modified 
    flag_modified(obj, data_field_name) 
+0

Questa risposta sembra essere rischiosa tuttavia, se si contrassegna l'attributo come modificato ma non ci sarà uno stato per esso in state_dict causerà KeyError. site-packages/sqlalchemy/orm/persistence.py ", riga 454, in _collect_update_commands value = state_dict [propkey] – Drachenfels

+0

Grazie! È possibile modificare anche l'id della chiave primaria utilizzando l'attributo set? –

0

l'approccio flag_modified funziona se si sa che l'attributo ha un valore di pre inviato. Documentazione di SQLAlchemy states:

Contrassegnare un attributo su un'istanza come "modificato".

Imposta il flag "modificato" sull'istanza e stabilisce un evento di modifica incondizionata per l'attributo specificato. L'attributo deve avere un valore presente, altrimenti viene generato un InvalidRequestError.

A partire dalla versione 1.2, se si vuole segnare una intera istanza poi flag_dirty è il solution:

Mark un'istanza come ‘sporco’, senza alcun attributo specifico menzionato.