2013-01-13 11 views
8

Ich versuche, eine Zeile von DB zu erhalten, ändern Sie diese Zeile und speichern Sie sie erneut.
Alles von sqlalchemyZeile in SqlAlchemy ORM aktualisieren

Mein Code

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

Leider funktioniert es nicht verwenden, weil ich RowProxy Objekt zu ändern versuchen. Wie kann ich tun, was ich will (laden, ändern und speichern (aktualisieren) Zeile) in SqlAlchemy ORM Weg?

+1

kurzer Blick Hinweis: Sie fügen Sie keine Objekte auf einer Sitzung zur Modifizierung. Sie fügen hinzu, wenn Sie eine neue Zeile erstellen. Normalerweise ändern Sie einfach das Proxy-Objekt und dann das Commit für das Sitzungsobjekt. Wenn Sie wirklich das ORM verwenden möchten, erstellen Sie normalerweise keine Abfrage in SQL und verwenden die Methode execute. Verwenden Sie den Abfragegenerator. – Keith

+0

Er sagte, er habe einen AttributeError beim Ändern des RowProxy-Objekts erhalten. Warum sollten Sie erwarten, dass das funktioniert? –

Antwort

13

Ich nehme an, dass Ihre Absicht ist, Object-Relational API zu verwenden. Um die Zeile in db zu aktualisieren, müssen Sie dazu das zugeordnete Objekt aus dem Tabellendatensatz laden und die Eigenschaft des Objekts aktualisieren.

Siehe Codebeispiel unten. Bitte beachten Sie, dass ich Beispielcode hinzugefügt habe, um ein neues zugeordnetes Objekt zu erstellen und einen ersten Datensatz in der Tabelle zu erstellen. Außerdem gibt es am Ende einen auskommentierten Code zum Löschen des Datensatzes.

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 stellt auch SQL Expression API, die direkt mit Tabellensätzen arbeiten können, ohne zugeordnete Objekte zu schaffen. In meiner Praxis verwenden wir in den meisten Anwendungen Object-Relation-API. Manchmal verwenden wir die SQL Expressions-API, wenn wir Low-Level-Db-Operationen wie das Einfügen oder Aktualisieren Tausender Datensätze mit einer Abfrage effizient durchführen müssen.

Direkte Links zu SQLAlchemy Dokumentation:

+0

Ist die einzige Option, um das ORM zu verwenden? Oder ist es auch mit der SQLAlchemy Expression Language möglich? –

Verwandte Themen