Коробка с питоном
543 subscribers
45 photos
118 links
Заметки от Python-разработчика: сниппеты, обзоры пакетов, новости и другая полезная информация.

Автор: @kiriharu
Download Telegram
Очень хороший доклад про SQLAlchemy. Автор рассказывает о Query, состоянии запроса внутри сессии, техниках загрузок связанных таблиц, отношениях и о многих других полезных вещах.
Не смотря на то, что докладу уже 2 года, многие вещи (всё таки работа с асинком поменялась) до сих пор актуальны.

#посмотреть #sqlalchemy
Нашел свежий доклад со сравнением использования CTE и SFW в Django ORM и SQLAlchemy, спойлер: джанга в такие штуки не умеет, пишите raw sql.

Ещё внезапно для себя узнал насколько алхимия мощная в плане рефлексии и как с ней легко работать используя уже существующую базу.

#посмотреть #sqlalchemy #django
О работе с PostgreSQL JSONB в SQLAlchemy

JSON поля в PostgreSQL - это действительно удобный способ хранения данных, наряду с реляционной моделью. Они могут понадобиться там, где нужно произвести денормализацию данных для ускорения работы или для хранения гетерогенных данных.

Алхимия поддерживает работу с JSON-полями нативно, поэтому мы можем добавлять эти поля в свои модельки. Но есть пара нюансов, связанных с тем, каким образом алхимия проверяет изменения в этих полях.

Допустим, есть у нас вот такой класс:

class Config(Base):
id = Column(Integer, primary_key=True)
config = Column(JSONB)
tablename = 'config'

А теперь попытаемся добавить запись и изменить её:

cfg = Config(
id=1,
config={'some_const': 1}
)

session.add(cfg)
session.commit()

cfg.config['test'] = 2

session.add(cfg)
session.commit()

# упадёт с assertion error
assert cfg.config['test'] == 2

Почему оно упадёт с assertion error?
Внимательно прочитаем документацию SQLAlchemy и найдем вот такой забавный пункт: The JSON type, when used with the SQLAlchemy ORM, does not detect in-place mutations to the structure. То есть, при изменения структуры нашего объекта Алхимия не понимает, произошло ли какое-то изменение или нет.
Есть 2 решения этой проблемы:

1) Использовать класс MutableDict, если у нас нет вложенности в JSONB объектах:
Просто оборачиваем этой штукой наш тип в модели и радуемся жизни. Выглядит это как-то так:
...
config = Column(MutableDict.as_mutable(JSONB))

2) Используем библиотеку sqlalchemy-json, если у нас есть вложенность:
В данном случае наше поле будет выглядить как-то так:
from sqlalchemy_json import mutable_json_type
...
config = Column(mutable_json_type(dbtype=JSONB, nested=True))

Ссылочки:
1) Adding mutability to json
2) Mutation tracking
3) Mutation tracking in nested JSON structures using SQLAlchemy

#sqlalchemy #рецепт