Найти - Пользователи
Полная версия: [sqlalchemy] - удаление объектов
Начало » Базы данных » [sqlalchemy] - удаление объектов
1 2 3
demas
j2a
Но ты можешь сделать что хочешь средствами SQL expression language.
А на сколько это корректно смешивать эти два подхода? Просто мне кажется, что в крупных проектах это не должно поощряться.

j2a
P.S. А в чем сермяжная правда? Какой смысл делать “копию” объекта для удаления из БД? Почему не воспользоваться самим объектом?
Да потому, что код написан так, что к моменту удаления объекта у меня его просто нет. Есть элемент управления заполненный данными и все. Код конечно можно переписать, просто хочу сначала с этим моментом разобраться.
j2a
demas
j2a
Но ты можешь сделать что хочешь средствами SQL expression language.
А на сколько это корректно смешивать эти два подхода? Просто мне кажется, что в крупных проектах это не должно поощряться.

j2a
P.S. А в чем сермяжная правда? Какой смысл делать “копию” объекта для удаления из БД? Почему не воспользоваться самим объектом?
Да потому, что код написан так, что к моменту удаления объекта у меня его просто нет. Есть элемент управления заполненный данными и все. Код конечно можно переписать, просто хочу сначала с этим моментом разобраться.
А ты не смешивай. Допиши метод к маппер-классу, который бы делал нужное.
bw
demas
Почему 2? Поле где “two” это вообще первичный ключ.
(*1*) print id
orig = session.query(Product).filter(Product.name==id).first()
(*2*) print orig.name
demas
Здесь просто считываются поля из интерфейса и порождается объект.
Но он не является у тебя (в таком состоянии, содя по коду) элементом базы и, как минимум, не подвязан к сесси. Вот после такого кода, он будет находится в базе и сесси и ты сможешь его удалить (код относится к SQLAlchemy 0.5, в ранних версиях небыло метода add, он заменил собой save):
s = Session()
s.add(product)
s.flush() # и/или s.commit(), если используешь транзакции
Всё, без создания новой сессии и без запроса product в базе, ты можешь обращаться к product:
s.delete(product)
s.flush() # и/или s.commit(), если используешь транзакции
s.close()
p.s. Опять же, точно не скажу, но кажется нет необходимости делать первый flush, что бы удалить объект. Если, конечно ты не хочешь что бы объект всё же отразился в БД.

..bw
demas
    def get_selected_product(self):
(model, iter) = self.treeview.get_selection().get_selected()
return Product(self.treestore.get_value(iter, 0),
self.treestore.get_value(iter, 1),
self.treestore.get_value(iter, 2),
self.treestore.get_value(iter, 3),
self.treestore.get_value(iter, 4))

def delete_product(self, widget):
print '=== delete ==='
session = Session()
del_obj = self.get_selected_product()
print del_obj.name
session.save(del_obj)
print 'a'
session.flush()
session.delete(del_obj)
print 'b'
session.commit()
session.flush()
=== delete ===
two
a
2008-10-16 14:00:12,832 INFO sqlalchemy.engine.base.Engine.0x..cc INSERT INTO product (name, category, fat, protein, carbo) VALUES (?, ?, ?, ?, ?)
2008-10-16 14:00:12,833 INFO sqlalchemy.engine.base.Engine.0x..cc
2008-10-16 14:00:12,834 INFO sqlalchemy.engine.base.Engine.0x..cc ROLLBACK

….

File “/var/lib/python-support/python2.5/sqlalchemy/engine/base.py”, line 942, in _handle_dbapi_exception
raise exceptions.DBAPIError.instance(statement, parameters, e, connection_invalidated=is_disconnect)
sqlalchemy.exceptions.IntegrityError: (IntegrityError) column name is not unique u'INSERT INTO product (name, category, fat, protein, carbo) VALUES (?, ?, ?, ?, ?)'
Я не могу сделать save() так как у меня уже есть такая запись в БД.
demas
    def delete_product(self, widget):
print '=== delete ==='
session = Session()
session.query(Product).filter_by(name = 'two').delete()
session.flush()
AttributeError: ‘Query’ object has no attribute ‘delete’
bw
> AttributeError: ‘Query’ object has no attribute ‘delete’
Я гворил что он появлился недавно, проверь версию SQLAlchemy.
Думаю что именно этот метод, последний, и будет оптимальным в твоем случае. Такой delete не будет загружать объект (опять, насколько мне известно, если использовать расширения в мапере, возможно, он все же будет загружаться).

..bw
demas
Поставил 1.5 - последний способ заработал.
Спасибо за терпение :)
demas
Кстати, еще маленький вопрос по теме - если кто-то объяснит - буду благодарен:

    	(model, iter) = self.treeview.get_selection().get_selected()
session = Session()
name = self.treestore.get_value(iter, 0)
session.query(Product).filter_by(name = name).delete()
session.flush()
session.commit()
2008-10-16 16:27:10,558 INFO sqlalchemy.engine.base.Engine.0x…6d2c
2008-10-16 16:27:10,559 INFO sqlalchemy.engine.base.Engine.0x…6d2c DELETE FROM product WHERE product.name = ?
2008-10-16 16:27:10,562 INFO sqlalchemy.engine.base.Engine.0x…6d2c
2008-10-16 16:27:10,563 INFO sqlalchemy.engine.base.Engine.0x…6d2c COMMIT
Все удалилось нормально.

А теперь чуть-чуть правим код:

    	(model, iter) = self.treeview.get_selection().get_selected()
session = Session()

#name = self.treestore.get_value(iter, 0)
product= Product(self.treestore.get_value(iter, 0),
self.treestore.get_value(iter, 1),
self.treestore.get_value(iter, 2),
self.treestore.get_value(iter, 3),
self.treestore.get_value(iter, 4))
name = product.name
session.query(Product).filter_by(name = name).delete()
session.flush()
session.commit()
2008-10-16 16:30:49,795 INFO sqlalchemy.engine.base.Engine.0x…3d2c
2008-10-16 16:30:49,796 INFO sqlalchemy.engine.base.Engine.0x…3d2c DELETE FROM product WHERE product.name = ?
2008-10-16 16:30:49,796 INFO sqlalchemy.engine.base.Engine.0x…3d2c
2008-10-16 16:30:49,799 INFO sqlalchemy.engine.base.Engine.0x…3d2c INSERT INTO product (name, category, fat, protein, carbo) VALUES (?, ?, ?, ?, ?)
2008-10-16 16:30:49,800 INFO sqlalchemy.engine.base.Engine.0x…3d2c
2008-10-16 16:30:49,801 INFO sqlalchemy.engine.base.Engine.0x…3d2c COMMIT
Откуда то взялся INSERT. Откуда?
Я всего лишь создал объект. Я не добавлял его в session.
bw
Ты можешь не делать flush перед commit, он выполнится автоматически.
Сложно сказать почему так получается, может ты не весь код показал? Если не добавляешь объект к сессии, то он не должен insert'иться.

..bw
PooH
demas
Да потому, что код написан так, что к моменту удаления объекта у меня его просто нет. Есть элемент управления заполненный данными и все. Код конечно можно переписать, просто хочу сначала с этим моментом разобраться.
Если я правильно разобрался в ситуации вам достаточно хранить ID объекта в своем дереве, этого будет достаточно для удаления из базы без всяких выкрутасов.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB