Форум сайта python.su
Подскажите, пожалуйста, почему вот такой код работает:
session = self.engine.createSession()
for each_product in session.query(Product):
print 'deleted %s' % each_product.name
session.delete(each_product)
session.commit()
session = self.engine.createSession()
for each_product in session.query(Product):
print 'deleted %s' % each_product.name
new_product = Product(each_product.name, each_product.category, each_product.fat, each_product.protein, each_product.carbo)
session.delete(new_product)
session.commit()
Офлайн
Нееееее. Читай http://www.sqlalchemy.org/docs/05/session.html#unitofwork_using_states – у тебя новый объект в состоянии pending.
Офлайн
Хм…
Почему новый? Он создан еще вчера и с тех пор я закрывал запущенную программу.
Pending - when you add() a transient instance, it becomes pending. It still wasn't actually flushed to the database yet, but it will be when the next flush occurs.Ну как он может быть не сброшен на диск, если после add я даже программу закрывал?
Офлайн
И потом, первым же скриптом я успешно удаляю записи.
Потом отдельным скриптом вставляю записи, завершаю его. А вторым (с созданием нового объекта) удалить уже не получается.
Или дело все-таки в Object States и я просто не понимаю чего-то глобального?
Офлайн
Человек, ты во втором примере создаешь новый объект (new_product = bla-bla) с такими же данными, как у старого. И новый несохраненный объект пытаешься удалить.
Офлайн
j2aАга. Именно это я и пытаюсь сделать :) Я просто удивлен, что здесь возникла проблема.
Человек, ты во втором примере создаешь новый объект (new_product = bla-bla) с такими же данными, как у старого. И новый несохраненный объект пытаешься удалить.
Офлайн
Все равно у меня не выходит…
session = Session()
id = self.get_selected_product().name
print id
orig = session.query(Product).filter(Product.name==id).first()
print orig.name
session.delete(orig)
session.commit()
session.flush()
Офлайн
Не знаю почему.
У тебя как минимум должно быть две строки “two”, если судить поприведенному коду. Вывод - это выхлоп другого кода.
Ты уверен, что после создания объекта ты делаешь flush/commit (flush, кстати, идет перед commit, после commit он теряет свой смысл, а commit используется, только если у тебя транзакция, похоже так оно и есть, иначе СУБД выдают ошибку, что транзакция не была начата)? Я вот про это “и порождаю новый экземпляр объекта Product (просто у меня уже был такой метод)”, в приведенном коде ты ничего не порождаешь.
> Ага. Именно это я и пытаюсь сделать :) Я просто удивлен, что здесь возникла проблема.
А я удивлен, что ты удивлен. Раньше, при использовании ORM, объект обязательно нужно было грузить, сейчас можно сделать:
session = Session()
session.query(Product).filter_by(id = 1).delete()
session.flush() # session.commit()
Отредактировано (Окт. 15, 2008 17:09:40)
Офлайн
demasЕсли в рамках ORM, то нужно чтобы связь объект<->запись БД была установлена. Если объект в состоянии pending, он не связан ни с какой записью в БД. Но ты можешь сделать что хочешь средствами SQL expression language.j2aАга. Именно это я и пытаюсь сделать :) Я просто удивлен, что здесь возникла проблема.
Человек, ты во втором примере создаешь новый объект (new_product = bla-bla) с такими же данными, как у старого. И новый несохраненный объект пытаешься удалить.
Ведь в моем новом объекте есть вся необходимая информация, чтобы удалить запись из базы. Теоретически sqlAlchemy может по маппингу определить какие поля в таблице ключевые и сгенерить delete from table where field = object.property. Но она так и не делает.
Отсюда и вопрос - если у меня нет объекта считанного из базы, но есть вся информация, необходимая для того чтобы создать его точную копию (все поля объектов совадают) я все равно должен вычитывать объект из базы перед его удалением. Так?
Отредактировано (Окт. 15, 2008 17:10:13)
Офлайн
bwОк, буду разбираться дальше.
Не знаю почему.
bwПочему 2? Поле где “two” это вообще первичный ключ.
У тебя как минимум должно быть две строки “two”, если судить поприведенному коду.
bw
Ты уверен, что после создания объекта ты делаешь flush/commit (flush, кстати, идет перед commit, после commit он теряет свой смысл, а commit используется, только если у тебя транзакция, похоже так оно и есть, иначе СУБД выдают ошибку, что транзакция не была начата)?
Я вот про это “и порождаю новый экземпляр объекта Product (просто у меня уже был такой метод)”, в приведенном коде ты ничего не порождаешь.
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))
bwУгу, понял. Спасибо.
p.s. И если ты при создании указываешь те же атрибуты атрибуты, что и у сушествующего, ты таким образом не ссылаешься на существующий, ты просто создаешь идентичный (при попытке сохранения такого объекта у тебя возникнут ожиданные проблемы с уникальными ключами).
Офлайн