2013-01-13 6 views
8

DBから行を取得しようとしていて、その行を変更してもう一度保存しています。私はRowProxyオブジェクトを変更しようとしていますので、SQLAlchemyのSqlAlchemyで行を更新するORM

私のコード

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

を使用して
すべては残念ながら、それは、動作しません。どのようにしてSqlAlchemy ORMの方法で(行のロード、変更、保存(更新))したいのですか?

+1

一目注:あなたが変更するためのセッションにオブジェクトを追加しないでください。新しい行を作成するときに追加します。通常は、プロキシオブジェクトを変更してセッションオブジェクトに対してコミットするだけです。また、ORMを実際に使用する場合は、通常SQLでクエリを作成せずにexecuteメソッドを使用します。クエリジェネレータを使用します。 – Keith

+0

彼はRowProxyオブジェクトを変更するときにAttributeErrorを得たと述べています。なぜあなたはそれが働くことを期待していますか? –

答えて

13

Object-Relational APIを使用するとします。 dbの行を更新するには、マップレコードをテーブルレコードから読み込んでオブジェクトのプロパティを更新する必要があります。

下記のコード例をご覧ください。 私は新しいマップされたオブジェクトを作成し、テーブルの最初のレコードを作成するためのサンプルコードを追加しました。また、レコードを削除するための最後のコードがコメントアウトされています。

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のにもマッピングされたオブジェクトを作成することなく、直接テーブルのレコードで作業することを可能にするSQL Expression APIを提供します。私の練習では、ほとんどのアプリケーションでObject-Relation APIを使用しています.1つのクエリで数千のレコードを挿入または更新するなど、低レベルのDB操作を効率的に実行する必要があるときにSQL Expressions APIを使用することがあります。 SQLAlchemyのドキュメントへ

の直接リンク:

+0

ORMを使用する唯一のオプションはありますか?あるいは、SQLAlchemy表現言語でも可能ですか? –

関連する問題