Подтвердить что ты не робот

Как удалить строки из таблицы с помощью запроса SQLAlchemy без ORM?

Я пишу быстрый и грязный mainteace script для удаления некоторых строк и хотел бы избежать необходимости переносить классы/сопоставления 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, как я должен это делать?

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Когда вы вызываете 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)