2013-01-13 6 views
8

Sto cercando di ottenere una riga dal DB, modificare quella riga e salvarla di nuovo.
Tutto utilizzando SQLAlchemyAggiornamento riga in SqlAlchemy ORM

Il mio codice

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() 

Purtroppo non funziona, perché sto cercando di modificare l'oggetto RowProxy. Come posso fare quello che voglio (caricare, modificare e salvare (aggiornare) riga) in modo SqlAlchemy ORM?

+1

nota rapida occhiata: non si aggiungono oggetti a una sessione di modifica. aggiungi quando crei una nuova riga. Normalmente, si modifica semplicemente l'oggetto proxy, quindi si esegue il commit sull'oggetto di sessione. Inoltre, se si desidera veramente utilizzare l'ORM, normalmente non si costruisce una query in SQL e si utilizza il metodo execute. Utilizza il generatore di query. – Keith

+0

ha detto di aver ricevuto un AttributeError durante la modifica dell'oggetto RowProxy. Perché ti aspetti che funzioni? –

risposta

13

Suppongo che l'intenzione sia quella di utilizzare Object-Relational API. Quindi per aggiornare la riga in db è necessario farlo caricando l'oggetto mappato dal record della tabella e aggiornando la proprietà dell'oggetto.

Vedere l'esempio di codice di seguito. Si noti che ho aggiunto un codice di esempio per la creazione di un nuovo oggetto mappato e la creazione del primo record nella tabella anche se alla fine è presente un codice commentato per l'eliminazione del record.

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 prevede inoltre SQL Expression API che permette di lavorare con i record della tabella direttamente senza creare oggetti mappati. Nella mia pratica utilizziamo l'API Object-Relation nella maggior parte delle applicazioni, a volte utilizziamo l'API di SQL Expressions quando è necessario eseguire operazioni DB di basso livello in modo efficiente, come l'inserimento o l'aggiornamento di migliaia di record con una query.

collegamenti diretti per la documentazione SQLAlchemy:

+0

È l'unica opzione per utilizzare l'ORM? O è anche possibile con SQLAlchemy Expression Language? –

Problemi correlati