Вопрос по orm, caching, sqlalchemy, python, autoload – sqlalchemy автозагрузка orm персистентность

5

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

class users(Base):
    __tablename__ = 'users'
    __table_args__ = {
        'autoload': True,
        'mysql_engine': 'InnoDB',
        'mysql_charset': 'utf8'
    }

Есть ли способ сериализации или кэширования автоматически загруженных метаданных / форм, поэтому нам не нужно проходить процесс автозагрузки каждый раз, когда нам нужно ссылаться на наши классы orm из других скриптов / функций?

Я смотрел на кеширование стакана и маринование, но не нашел четкого ответа, если это возможно или как это сделать.

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

Есть идеи?

В моем случае разработка базы данных осуществляется отдельно, это означает, что приложение не имеет полного контроля. Тем не менее, я нашел способ выбора метаданных, поэтому мне нужно только один раз отразить через соединение с базой данных, чтобы создать рассол, - время, когда я использую метаданные для отражения, для отражения которого требуется доля времени, связанного с соединением дБ (см. Ниже). user1572502
Почему бы вам не сделать наоборот: определить полную модель в SA. Как побочный эффект, это будет действовать как ваш источник контроля для схемы базы данных.Of course, this only works if your SA application has the primary control of the database(s) you are working with van

Ваш Ответ

1   ответ
5

Что я сейчас делаю, так это выбираю метаданные после запуска отражения через соединение с базой данных (MySQL), и как только становится доступен выбор, используйте эти метаданные для отражения в схеме с метаданными, привязанными к движку SQLite.

cachefile='orm.p'
dbfile='database'
engine_dev = create_engine(#db connect, echo=True)
engine_meta = create_engine('sqlite:///%s' % dbfile,echo=True)
Base = declarative_base()
Base.metadata.bind = engine_dev
metadata = MetaData(bind=engine_dev)

# load from pickle 
try:
    with open(cachefile, 'r') as cache:
        metadata2 = pickle.load(cache)
        metadata2.bind = engine_meta
        cache.close()
    class Users(Base):
        __table__ = Table('users', metadata2, autoload=True)

    print "ORM loaded from pickle"

# if no pickle, use reflect through database connection    
except:
    class Users(Base):
        __table__ = Table('users', metadata, autoload=True)

print "ORM through database autoload"

# create metapickle
metadata.create_all()
with open(cachefile, 'w') as cache:
    pickle.dump(metadata, cache)
    cache.close()

Любые комментарии, если это хорошо (это работает) или есть что-то, что я могу улучшить?

Вы могли бы упростить это, просто используя один объект MetaData, а также просто сделать «quot; if os.path.exists (cachefile)» & quot; чтобы определить, снимаете ли вы травление или нет. «Таблица (« пользователи », метаданные, autoload = True)» и такое необходимо указывать только один раз, поскольку, как вы уже видели, оно пропускает отражение, если таблица уже находится в метаданных.
Я думаю, что нет необходимости закрывать файл при использовании внутриwith заявление, но это не связано. Ваш подход кажется интересным, он работает, как ожидалось?

Похожие вопросы