2013-01-13 3 views
8

Я пытаюсь получить строку из БД, изменить эту строку и сохранить ее снова.
Все с помощью 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() 

К сожалению, это не работает, потому что я пытаюсь изменить RowProxy объект. Как я могу сделать то, что хочу (загрузить, изменить и сохранить (обновить) строку) в ORM-методе SqlAlchemy?

+1

быстрый взгляд примечание: не добавлять объекты к сеансу для изменения. вы добавляете при создании новой строки. Обычно вы просто изменяете прокси-объект, а затем фиксируете его на объекте сеанса. Кроме того, если вы действительно хотите использовать ORM, вы обычно не создаете запрос в SQL и не используете метод execute. Используйте генератор запросов. – Keith

+0

он сказал, что получил атрибут AttributeError при изменении объекта RowProxy. Почему вы ожидаете, что это сработает? –

ответ

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, что позволяет работать с записями таблицы непосредственно без создания сопоставленных объектов. В моей практике мы используем API Object-Relation в большинстве приложений, иногда мы используем SQL Expressions API, когда нам нужно выполнять операции с низким уровнем db эффективно, например, вставлять или обновлять тысячи записей одним запросом.

Прямые ссылки на SQLAlchemy документации:

+0

Является единственным вариантом использования ORM? Или это также возможно с языком выражения SQLAlchemy? –

Смежные вопросы