Зачем нужно повторять автопокрытие?(SQLAlchemy) - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь понять код, который выполняет примерно следующее:

# db.py module

engine = create_engine(DB_URL, pool_timeout=20, pool_recycle=1)

def get_session():
    return scoped_session(sessionmaker(bind=engine, expire_on_commit=False))()

def get_base():
    base = automap_base()
    base.prepare(engine, reflect=True)
    return base

base = get_base()
User = base.classes.user

в некоторой функции:

# other.py module
from db import get_base, get_session, User

def some_func():
   sess = get_session()
   # do something with sess and User:
   user = sess.query(User).first()

   User2 = get_base().classes.user
   try:
      check = sess.query(User2).first()
   except:
      sess.rollback()

   # do more with sess
   sess.commit()

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

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

В чем может быть смысл?

Хотя моё предположение о получении того же объекта неверно:

(Pdb) pp user
<sqlalchemy.ext.automap.user object at 0x7f62e1a57390>
(Pdb) pp check
<sqlalchemy.ext.automap.user object at 0x7f62e0e93750>
(Pdb) pp user == check
False
(Pdb) pp user.id
1L
(Pdb) pp check.id
1L

(id является первичным ключом, то есть уникальным)

Так что, похоже, SQLAlchemy хранит объекты из разных баз отдельно.

На данный момент я думаю, что этот трюк позволяетнапример, проверка существования пользователя вне текущей транзакции.

1 Ответ

0 голосов
/ 15 февраля 2019

В большинстве случаев это не нужно и просто замедляет работу приложения.Схема базы данных обычно не меняется слишком часто во время работы приложения, и простые изменения не должны иметь значения (см. «Независимость данных» ).Переделать рефлексию и т. Д. - это просто то, что люди, кажется, делают - возможно, из-за боязни использования глобалов.С другой стороны, в вашем примере сначала кажется, что в db.py отражение выполняется только один раз для создания глобальных классов base и User.

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

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

...