2013-01-13 11 views
8

Próbuję uzyskać wiersz z bazy danych, zmienić ten wiersz i zapisać go ponownie.
Wszystko za pomocą sqlalchemyAktualizowanie wiersza w narzędziu SqlAlchemy ORM

mojego kodu

from sqlalchemy import Column, DateTime, Integer, String, Table, MetaData 
from sqlalchemy.orm import mapper 
from sqlalchemy import create_engine, orm 

metadata = MetaData() 

product = Table('product', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('name', String(1024), nullable=False, unique=True), 

) 

class Product(object): 
    def __init__(self, id, name): 
     self.id = id 
     self.name = name 

mapper(Product, product) 


db = create_engine('sqlite:////' + db_path) 
sm = orm.sessionmaker(bind=db, autoflush=True, autocommit=True, expire_on_commit=True) 
session = orm.scoped_session(sm) 

result = session.execute("select * from product where id = :id", {'id': 1}, mapper=Product) 
prod = result.fetchone() #there are many products in db so query is ok 

prod.name = 'test' #<- here I got AttributeError: 'RowProxy' object has no attribute 'name' 

session .add(prod) 
session .flush() 

Niestety to nie działa, ponieważ staram się modyfikować RowProxy obiekt. Jak mogę zrobić, co chcę (załadować, zmienić i zapisać (zaktualizować) wiersz) w SqlAlchemy ORM sposób?

+1

szybkie spojrzenie uwaga: nie dodawać obiekty do sesji dla modyfikacji. dodajesz podczas tworzenia nowego wiersza. Zwykle wystarczy zmodyfikować obiekt proxy, a następnie zatwierdzić obiekt sesji. Ponadto, jeśli naprawdę chcesz użyć ORM, zwykle nie tworzysz zapytania w SQL i używasz metody execute. Użyj generatora zapytań. – Keith

+0

powiedział, że dostał AttributeError podczas modyfikowania obiektu RowProxy. Dlaczego miałbyś oczekiwać, że to zadziała? –

Odpowiedz

13

Zakładam, że Twoim zamiarem jest użycie numeru Object-Relational API. Aby zaktualizować wiersz w db, musisz to zrobić, ładując zmapowany obiekt z rekordu tabeli i aktualizując właściwość obiektu.

Proszę zobaczyć przykład kodu poniżej. Uwaga: dodałem przykładowy kod do tworzenia nowego odwzorowanego obiektu i tworzenia pierwszego rekordu w tabeli, a na końcu jest skomentowany kod do usunięcia rekordu.

from sqlalchemy import Column, DateTime, Integer, String, Table, MetaData 
from sqlalchemy.orm import mapper 
from sqlalchemy import create_engine, orm 

metadata = MetaData() 

product = Table('product', metadata, 
    Column('id', Integer, primary_key=True), 
    Column('name', String(1024), nullable=False, unique=True), 

) 

class Product(object): 
    def __init__(self, id, name): 
     self.id = id 
     self.name = name 
    def __repr__(self): 
     return "%s(%r,%r)" % (self.__class__.name,self.id,self.name) 

mapper(Product, product) 


db = create_engine('sqlite:////temp/test123.db') 
metadata.create_all(db) 

sm = orm.sessionmaker(bind=db, autoflush=True, autocommit=True, expire_on_commit=True) 
session = orm.scoped_session(sm) 

#create new Product record: 
if session.query(Product).filter(Product.id==1).count()==0: 

    new_prod = Product("1","Product1") 
    print "Creating new product: %r" % new_prod 
    session.add(new_prod) 
    session.flush() 
else: 
    print "product with id 1 already exists: %r" % session.query(Product).filter(Product.id==1).one() 

print "loading Product with id=1" 
prod = session.query(Product).filter(Product.id==1).one() 
print "current name: %s" % prod.name 
prod.name = "new name" 

print prod 


prod.name = 'test' 

session.add(prod) 
session.flush() 

print prod 

#session.delete(prod) 
#session.flush() 

PS SQLAlchemy zapewnia również SQL Expression API który pozwala pracować z rekordami tabeli bezpośrednio bez tworzenia odwzorowanych obiektów. W mojej praktyce używamy API Object-Relation w większości aplikacji, czasami używamy API SQL Expressions, gdy potrzebujemy wydajnie wykonywać operacje na niskim poziomie db, np. Wstawiając lub aktualizując tysiące rekordów za pomocą jednego zapytania.

bezpośrednie linki do dokumentacji sqlalchemy:

+0

Czy jest jedyną opcją użycia ORM? A może jest to również możliwe w języku ekspresji SQLAlchemy? –

Powiązane problemy