2015-04-23 10 views
6

Czy istnieje sposób zmusić obiekt odwzorowaną przez SQLAlchemy aby uznać dirty? Na przykład, biorąc pod uwagę kontekst sqlalchemy'S Object Relational Tutorial problem jest wykazaćsiła obiekt będzie `dirty` w SQLAlchemy

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

plonowanie,

IdentitySet([]) 

szukam sposób zmusić użytkownika a w brudnym stanie.

Ten problem powstaje, ponieważ klasa odwzorowana za pomocą sqlalchemy przejmuje kontrolę nad metodami getter/setter atrybutu, a to zapobiega zapisywaniu zmian przez sqlalchemy.

Odpowiedz

13

natknąłem się na ten sam problem niedawno i nie było oczywiste.

Przedmioty same w sobie nie są brudne, ale ich atrybuty są. Ponieważ SQLAlchemy wypisze tylko zmienione atrybuty, a nie cały obiekt, o ile wiem.

Jeśli ustawisz atrybut używając set_attribute i różni się od pierwotnych danych atrybutów, SQLAlchemy zakłada się obiekt jest brudny (TODO: Muszę szczegóły jak to robi porównanie):

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

Jeśli aby zaznaczyć obiekt brudną niezależnie od pierwotnej wartości atrybutu, nie ważne czy to się zmieniło, czy nie, należy flag_modified:

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

Ta odpowiedź wydaje się być jednak ryzykowna, jeśli oznaczysz atrybut jako zmodyfikowany, ale nie będzie dla niego stanu w stanie_w stanie, spowoduje to KeyError. site-packages/sqlalchemy/orm/persistence.py ", wiersz 454, w _collect_update_commands wartość = state_dict [propkey] – Drachenfels

+0

Dzięki! Czy jest możliwa zmiana identyfikatora klucza głównego przy użyciu atrybutu zestawu? –

0

podejście flag_modified działa, jeśli ktoś wie, że atrybut ma wartość przed wysłane. Dokumentacja SQLAlchemy: states:

Oznaczyć atrybut w instancji jako "zmodyfikowany".

Spowoduje to ustawienie flagi "modified" na instancji i ustanowi bezwarunkowe zdarzenie zmiany dla danego atrybutu . Atrybut musi mieć wartość , inaczej podniesiony zostanie InvalidRequestError.

Począwszy od wersji 1.2, jeśli chce się oznaczyć całą instancję następnie flag_dirty jest solution:

Mark wystąpienie jako „brudne” bez określonego atrybutu wymienione.