Давайте начнем с определения моего сопоставленного класса
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.types import JSON
from sqlalchemy.ext.mutable import MutableDict
from sqlalchemy import Column, Integer
base = declarative_base()
class MinimalExample(Base):
__tablename__ = 'users'
id = Column(Integer)
data = Column(MutableDict.as_mutable(JSON))
Допустим, у меня в таблице есть строка с id=1
и data={'key_0': 1}
Я могу запросить ее через session
объект довольно легко
first_row = session.query(MinimalExample)\
.filter(MinimalExample.id==1)\
.first()
И оттуда я могу изменить поле JSON любым способом и обновить базу данных:
first_row.data['key_2'] = 1
session.commit()
Приведенный выше код работает (потому что мы пометили JSONполе как изменяемое условие, нам не нужно помечать его как грязное вручную)
session.query(MinimalExample.data)\
.filter(MinimalExample.id==1)\
.first()
>>> {'key_0': 1, 'key_2': 1}
Однако это означает, что мне нужно запросить все строки, которые я хочу изменить, на моем локальном компьютере, что простослишком медленно / у меня недостаточно памяти.
Я ищу способ использования функции sqlalchemy.update
для получения того же результата
Вот что я уже пробовал:
from sqlalchemy import update
stmt = update(MinimalExample)
.where(MinimalExample.id=1)\
.values(MinimalExample.data={'key_1': 1})
session.execute(stmt)
session.commit()
, который просто собирается заменить поле data
в моей строке словарем {'key_1': 1}
Что-то похожее на это похоже на путь:
(РЕДАКТИРОВАТЬ: нашел способ исправить мой предыдущий код, чтобы он больше не выдавал ошибку, просто поставив* объект в словарь)
stmt = update(MinimalExample)
.where(MinimalExample.id=1)\
.values({MinimalExample.data['key_1']:1})
, глядя на строку этого оператора, кажется довольно хорошим
str(stmt)
>>> 'UPDATE users SET data[:data_1]=:param_1 WHERE users.id = :id_1'
Однако выполнение этого оператора приводит к ProgrammingError: (MySQLdb._exceptions.ProgrammingError) (1064, 'You have an error in your SQL syntax
...
Есть мысли по этому поводу? Бонусные баллы, если я могу обновить несколько строк одновременно