10

DB から行を取得し、その行を変更して再度保存しようとしています。
SqlAlchemyを使用してすべて

私のコード

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

残念ながら、RowProxy オブジェクトを変更しようとしているため、機能しません。SqlAlchemy ORM の方法で、必要なこと (行のロード、変更、および保存 (更新)) を行うにはどうすればよいですか?

4

1 に答える 1

14

あなたの意図は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 式 APIも提供します。私の実践では、ほとんどのアプリケーションで Object-Relation API を使用しています。1 つのクエリで何千ものレコードを挿入または更新するなど、低レベルのデータベース操作を効率的に実行する必要がある場合は、SQL Expressions API を使用することがあります。

SQLAlchemy ドキュメントへの直接リンク:

于 2013-01-14T17:11:46.197 に答える