Если есть следующие настройки ОРМА в SQLAlchemy:SQLAlchemy, жадная загрузка на объекте обновления
class Foo(Base):
id = Column(Integer, primary_key=True)
status = Column(String)
barId = Column(Integer, ForeignKey("bar.id"))
bar = relationship("Bar", lazy="joined")
class Bar(Base):
id = Column(Integer, primary_key=True)
Так что я хотел бы всегда иметь соответствующий объект Bar, доступный для каждого объекта Foo. Я часто отделяю объекты Foo от сеанса и продолжаю использовать его значения и значения Bar. Время от времени мне нужно обновить поле статуса Foo. В этом случае я создаю новый сеанс, добавляю объект foo в сеанс и фиксирую его. После фиксации объект Bar, связанный с объектом Foo, недействителен, но не перезагружается неявным обновлением объекта Foo. После отсоединения объекта Foo от сеанса объект Bar больше не может использоваться. Единственный способ, с которым я нашел работу, - это явно загружать объект bar после совершения foo.
Пример работы потока:
session = Session()
foo = session.query(Foo).get(id) <-- foo.bar is automatically eager loaded
session.close()
....
session = Session()
session.add(foo)
foo.status = 'done'
session.commit() <-- foo is commited and refreshed, foo.bar is not
session.refresh(foo) <-- same here, foo.bar is not loaded
#foo.bar <-- only explicit eager loading foo.bar here works
session.close()
....
foo.bar <-- error if not explicitly eager loaded
Я хотел бы использовать эту установку для нескольких из тех малых Бара, как объекты. Требование, чтобы я помнил, чтобы всегда явно перезагружать, объект foo.bar подвержен ошибкам. Поэтому мой вопрос: могу ли я загрузить загрузку foo.bar во всех ситуациях, будь то запрос(), commit() (неявное обновление) или (явное) обновление()?
В моей конкретной установке 's.commit()' делает выбор в объекте foo без присоединения к нему со строкой (прежде чем я коснусь любого attr). Я не знаю, почему. Я ошибочно принял его за неявное обновление, как вы указали. Я не могу воспроизвести это с помощью вашей маленькой демонстрации. Нежелательная загрузка работает с явным 's.refresh (foo)'. Я пропустил это так или иначе, я все еще многому научился/экспериментировал с SQLAlchemy. – dieterg
SQLAlchemy не рекомендует использовать объекты в их «отключенном» состоянии. Мои объекты Foo живут по нескольким HTTP-запросам, и я всегда закрываю сеанс orm в конце запроса. Мне нужно только обновить объект foo. 1/100 запрашивает другие 99. Я просто использую данные. Какой дизайн вы тогда порекомендовали бы? 1) Скопируйте данные Foo и Bar в объекты non orm и запрашивайте, если мне нужно обновить. 2) Откройте новый сеанс orm, даже если мне не нужно обновлять/обновлять Foo. 3) ... – dieterg
обычно веб-приложение загружает все данные, необходимые для каждого запроса. если вы загружаете свой объект Foo по запросу номер один, тогда запрос номер два появится через шесть часов, вы сохранили эти объекты «Foo» в памяти все эти шесть часов? Откуда вы знаете, что они все еще актуальны? Это действительно шаблон кэширования.Рекомендация SQLAlchemy для кэширования заключается в том, что объекты повторно присоединяются или объединяются в новый сеанс по каждому запросу - см. [Кэширование кистей] (http://docs.sqlalchemy.org/en/rel_0_8/orm/examples.html#dogpile-caching) для рекомендуемых рекомендаций по проектированию. – zzzeek