Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 16, 2008 10:49:33

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

[sqlalchemy] - удаление объектов

j2a
Но ты можешь сделать что хочешь средствами SQL expression language.
А на сколько это корректно смешивать эти два подхода? Просто мне кажется, что в крупных проектах это не должно поощряться.

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



Офлайн

#2 Окт. 16, 2008 12:13:00

j2a
От:
Зарегистрирован: 2006-06-29
Сообщения: 869
Репутация: +  1  -
Профиль   Отправить e-mail  

[sqlalchemy] - удаление объектов

demas
j2a
Но ты можешь сделать что хочешь средствами SQL expression language.
А на сколько это корректно смешивать эти два подхода? Просто мне кажется, что в крупных проектах это не должно поощряться.

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



Офлайн

#3 Окт. 16, 2008 12:17:45

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

[sqlalchemy] - удаление объектов

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



Отредактировано (Окт. 16, 2008 12:20:38)

Офлайн

#4 Окт. 16, 2008 13:02:35

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

[sqlalchemy] - удаление объектов

    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() так как у меня уже есть такая запись в БД.



Офлайн

#5 Окт. 16, 2008 13:06:14

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

[sqlalchemy] - удаление объектов

    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’



Офлайн

#6 Окт. 16, 2008 14:37:36

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

[sqlalchemy] - удаление объектов

> AttributeError: ‘Query’ object has no attribute ‘delete’
Я гворил что он появлился недавно, проверь версию SQLAlchemy.
Думаю что именно этот метод, последний, и будет оптимальным в твоем случае. Такой delete не будет загружать объект (опять, насколько мне известно, если использовать расширения в мапере, возможно, он все же будет загружаться).

..bw



Офлайн

#7 Окт. 16, 2008 15:17:10

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

[sqlalchemy] - удаление объектов

Поставил 1.5 - последний способ заработал.
Спасибо за терпение :)



Офлайн

#8 Окт. 16, 2008 15:36:37

demas
От:
Зарегистрирован: 2008-09-10
Сообщения: 60
Репутация: +  0  -
Профиль   Отправить e-mail  

[sqlalchemy] - удаление объектов

Кстати, еще маленький вопрос по теме - если кто-то объяснит - буду благодарен:

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



Офлайн

#9 Окт. 16, 2008 17:37:07

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

[sqlalchemy] - удаление объектов

Ты можешь не делать flush перед commit, он выполнится автоматически.
Сложно сказать почему так получается, может ты не весь код показал? Если не добавляешь объект к сессии, то он не должен insert'иться.

..bw



Офлайн

#10 Окт. 17, 2008 05:39:18

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

[sqlalchemy] - удаление объектов

demas
Да потому, что код написан так, что к моменту удаления объекта у меня его просто нет. Есть элемент управления заполненный данными и все. Код конечно можно переписать, просто хочу сначала с этим моментом разобраться.
Если я правильно разобрался в ситуации вам достаточно хранить ID объекта в своем дереве, этого будет достаточно для удаления из базы без всяких выкрутасов.



Вот здесь один из первых отарков съел лаборанта. Это был такой умный отарк, что понимал даже теорию относительности. Он разговаривал с лаборантом, а потом бросился на него и загрыз…

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version