Как удалить строки из таблицы, используя запрос SQLAlchemy без ORM? - PullRequest
29 голосов
/ 27 марта 2012

Я пишу быстрый и грязный сценарий обслуживания для удаления некоторых строк и хотел бы избежать переноса моих классов / отображений ORM из основного проекта.У меня есть запрос, который выглядит примерно так:

address_table = Table('address',metadata,autoload=True)
addresses = session.query(addresses_table).filter(addresses_table.c.retired == 1)

В соответствии со всем, что я прочитал, если я использовал ORM (не просто таблицы) и передал что-то вроде:

addresses = session.query(Addresses).filter(addresses_table.c.retired == 1)

Я мог бы добавить .delete() к запросу, но когда я пытаюсь сделать это, используя только таблицы, я получаю жалобу:

File "/usr/local/lib/python2.6/dist-packages/sqlalchemy/orm/query.py", line 2146, in delete
    target_cls = self._mapper_zero().class_
AttributeError: 'NoneType' object has no attribute 'class_'

Это имеет смысл как таблица, а не класс,Я довольно зеленый, когда дело доходит до SQLAlchemy, как я должен идти об этом?

Ответы [ 2 ]

35 голосов
/ 27 марта 2012

Просматривая некоторый код, где я делал нечто подобное, я думаю, что это будет делать то, что вы хотите.

d = addresses_table.delete().where(addresses_table.c.retired == 1)
d.execute()

Вызов delete() для объекта таблицы дает вам sql.expression (если память служит), что вы потом казните.Выше я предполагал, что таблица связана с соединением, что означает, что вы можете просто вызвать execute() для нее.Если нет, вы можете передать d на execute(d) для соединения.

См. Документы здесь .

25 голосов
/ 01 декабря 2015

Когда вы вызываете delete() из объекта запроса, SQLAlchemy выполняет массовое удаление . И вам нужно выбрать стратегию для удаления подходящих объектов из сеанса . Смотри документацию здесь .

Если вы не выберете стратегию удаления совпадающих объектов из сеанса, SQLAlchemy попытается оценить критерии запроса в Python непосредственно для объектов в сеансе. Если оценка критериев не выполнена, возникает ошибка.

Это то, что происходит с вашим удалением.

Если вы хотите удалить только записи и не заботитесь о записях в сеансе после удаления, вы можете выбрать стратегию, игнорирующую синхронизацию сеанса:

address_table = Table('address', metadata, autoload=True)
addresses = session.query(address_table).filter(address_table.c.retired == 1)
addresses.delete(synchronize_session=False)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...