[Python] Mutazione di un oggetto dall'interno...

Manlio Perillo manlio_perillo a libero.it
Ven 23 Feb 2007 18:34:40 CET


Massimo ha scritto:
> Manlio Perillo ha scritto:
> [...]
> 
>> In linea di massima quello che vuoi fare non mi sembra il modo 
>> migliore di procedere.
>>
>> Perchè ti serve una cosa del genere?
> 
> Sto costruendo un "coso" per arrivare a fare cose tipo:
> 
> workspace = #inizializzazioni varie di dbms, session, etc.
> 
> oggetto = qualcosa(workspace)
> 
> oggetto.pk1=chiave1
> oggetto.pk2=chiave2
> oggetto.read()
> 
> ed a quel punto avere in "oggetto" i dati corrispondenti a quella pk nel 
> dbms (se esistente).
> 

Ma per fare questo non vedo perchè complicarsi la vita.

> (In realtà il problema originale è che non riesco a fare l'update di un 
> oggetto con SQLAlchemy, a meno che non sia caricato da session.query() e 
> poi modificato).
> 

Tieni conto che con SQLAlchemy non puoi modificare le primary key di un 
oggetto, tramite l'ORM.

Questo è un limite noto, c'è qualche discussione negli archivi della 
mailing list.

> L'idea era di fare un oggetto nuovo, in ogni caso. Poi quando vengono 
> inseriti i vari valori (controllo ridefinendo __setattr__) verifico se 
> la chiave primaria sia completa, ed a quel punto tento di leggere il 
> corrispondente oggetto dal dbms. Se non c'è non faccio nulla (l'oggetto 
> è nuovo, e quindi quello già istanziato mi va bene com'è) ma se esiste 
> invece di lavorare su un "nuovo" vorrei caricare i dati di quello 
> esistente e, di li in avanti, casomai, modificarli fino al successivo 
> .flush() (che in questo caso farà un update e non un insert).
> 

Non sono proprio sicuro di capire la logica del tutto.
Quando vuoi salvare un oggetto, lo crei e quindi fai sess.save(obj) .
Se lo vuoi caricare fai sess.load(pk)

In genere le operazioni "crea nuovo" e "modifica esistente" sono ben 
separate, ma sembra esserci diversa gente per cui non è così (tanto che 
MySQL ha un INSERT OR UPDATE).

> Ma non ne sto venendo fuori, non riesco a fare l'update ma solo 
> l'inserimento di nuovi oggetti.
> 

Se cambi la primary key, questo è normale.
Ma, di solito, la primary key non dovrebbe essere modificata;

> [...]
> 
>> In teoria quindi bastarebbe fare
>> self.__dict__.update(tmp.__dict__)
> 
> Si, giusto. Io avevo fatto stupidamente self.__dict__ = tmp.__dict__ 
> scoprendo che non era la via giusta.
> Usando .__dict__.update() ho in effetti i dati che mi servono. Dovrei 
> verificare però con oggetti complessi, con relazioni, come si 
> comporterebbe...
> In ogni caso anche adesso il tentativo di .save_or_update() e .flush() 
> non mi modifica i dati su disco... :(
> 

Come controlli che i dati siano davvero aggiornati?

In questo momento sto avendo un problema analogo anche io, ma è 
sess.query che sembra non mi riporti lo stato aggiornato (mi è successo 
anche tempo fa ed avevo risolto).

>> Ma non tutto lo stato si trova nel dizionario, ci sono anche le property.
>> Così su due piedi non so dirti come fare a copiare tutto.
> 
> Già...
> 

Un'altra soluzione è usare il pattern proxy.

class Proxy(object):
    def __init__(self, obj):
       self.obj = obj

    ...__setattr__/__getattr__

In questo caso ti basta modificare self.obj.



> [...]
>>> p.s. ho provato ad iscrivermi alla ml di SQLAlchemy, gestita da 
>>> google, e ricevo i messaggi ma non riesco a spedirne. Qualcuno l'ha 
>>> mai usata e mi può gentilmente suggerire "le basi"? Grazie ancora...
>>
>> Google non ti manda i messaggi che tu hai spedito, come succede in 
>> questa mailing list, ad esempio.
>> Hai provavo a vedere dall'interfaccia web?
> 
> No, il problema è proprio che mi ritornano indietro i messaggi che 
> spedisco. Ma ho usato il mio account, non uno di google... si potrà fare 
> lostesso, io penso, no?
> 

Sembra proprio di no.


Saluti  Manlio Perillo


Maggiori informazioni sulla lista Python