Определение фактического загруженного / выгруженного состояния объекта sqlalchemy и его отношений - PullRequest
2 голосов
/ 15 июня 2011

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

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

items_table = Table("invtypes", gdata_meta,
                    Column("typeID", Integer, primary_key = True),
                    Column("typeName", String, index=True),
                    Column("groupID", Integer, ForeignKey("invgroups.groupID"), index=True))

mapper(Item, items_table,
       properties = {"group" : relation(Group, backref = "items"),
                     "ID" : synonym("typeID"),
                     "name" : synonym("typeName")})

groups_table = Table("invgroups", dbmetadata,
                     Column("groupID", Integer, primary_key = True),
                     Column("groupName", String))

mapper(Group, groups_table,
       properties = {"ID" : synonym("groupID"),
                     "name" : synonym("groupName")})

Затем мы выбираем некоторый объект Item и одну из групп:

engine = create_engine("sqlite:///<path-to-db>", echo=True)
Session = sessionmaker(bind=engine)
session = Session()

itm = session.query(Item).get(11184)   #1
grp = session.query(Group).get(831)    #2

В данном конкретном случае itm.groupID = 831, поэтому группа itm уже загружена в память. Тем не менее:

* * 1010

SQLAlchemy указывает, что свойство / отношение группы 'itm' выгружено. Однако в этом случае при доступе к ней не выдаются запросы к базовой базе данных, поскольку она уже загружена в строке с меткой # 2. После первого доступа он больше не помечается как выгруженный.

Теперь давайте закончим с примером выше и поговорим в общем. При доступе к свойству группы объекта Item на группу с запрошенным идентификатором можно уже ссылаться где-то (т. Е. Уже сопоставлено в текущем сеансе) или существовать только в базовой базе данных.

Моя текущая цель - найти способ надежно определить, загружен ли уже в память Item с данным идентификатором и свойством / отношением 'group' ИЛИ ​​выполнять загрузку, затем доступ к itm.group, и если SQLAlchemy не может что-то извлечь из него его объектной карты и собирается выполнить запрос к базовой базе данных - перехватить его и выполнить другой запрос к базе данных. Это должно гарантировать, что для загрузки всего, что мне нужно, требуется не более одного запроса к базе данных (с энергичной загрузкой в ​​случае необходимости) или ноль запросов, если все уже загружено.

Как я описал в одном из приведенных выше абзацев, attribute.instance_state (). Unloaded не является надежным способом. Он не обнаруживает фактическое загруженное состояние свойства / отношения, к которому никогда не обращались.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...