简体   繁体   English

sqlalchemy表架构自动加载

[英]sqlalchemy table schema autoload

I am creating a sql alchemy table like so: 我正在创建一个像这样的SQL炼金术表:

myEngine = self.get_my_engine() # creates engine
metadata = MetaData(bind=myEngine)
SnapshotTable = Table("mytable", metadata, autoload=False, schema="my schema")

I have to use autoload false because the table may or may not exist (and that code has to run before the table is created) 我必须使用自动加载假,因为表可能存在或可能不存在(并且该代码必须在创建表之前运行)

The problem is, if I use autoload = False, when I try to query the table (after it was created by another process) doing session.query(SnapshotTable) I get an: 问题是,如果我使用autoload = False,当我尝试查询表(在由另一个进程创建之后)执行session.query(SnapshotTable)我得到一个:

InvalidRequestError: Query contains no columns with which to SELECT from.

error; 错误; which is understandable because the table wasn't loaded yet. 这是可以理解的,因为该表尚未加载。

My question is: how do I "load" the table metadata after it has been defined with autoload = False. 我的问题是:如何在使用autoload = False定义表元数据后“加载”表元数据。

I looked at the schema.py code and it seems that I can do: 我查看了schema.py代码,似乎我可以这样做:

SnapshotTable._autoload(metadata, None, None)

but that doesn't look right to me...any other ideas or thoughts? 但这对我来说并不合适......任何其他想法或想法?

Thanks 谢谢

First declare the table model: 首先声明表模型:

class MyTable(Base):
    __table__ = Table('mytable', metadata)

Or directly: 或直接:

MyTable = Table("mytable", metadata)

Then, once you are ready to load it, call this: 然后,一旦准备加载它,请调用:

Table('mytable', metadata, autoload_with=engine, extend_existing=True)

Where the key to it all is extend_existing=True . 其中的关键是extend_existing = True

All credit goes to Mike Bayer on the SQLAlchemy mailing list. 所有功劳都归功于SQLAlchemy邮件列表中的Mike Bayer。

I guess that problem is with not reflected metadata. 我想这个问题是没有反映元数据。 You could try to load metadata with method this call bevore executing any query : 您可以尝试使用此调用bevore执行任何查询的方法加载元数据:

metadata.reflect() 

It will reload definition of table, so framework will know how to build proper SELECT . 它将重新加载表的定义,因此框架将知道如何构建适当的SELECT And then calling 然后打电话

if SnapshotTable.exists :
     SnapshotTable._init_existing()

I was dealing with this issue just last night, and it turns out that all you need to do is load all available table definitions from the database with the help of metadat.reflect . 我昨晚正在处理这个问题,事实证明,你需要做的就是在metadat.reflect的帮助下从数据库中加载所有可用的表定义。 This is very much similar to @fgblomqvist's solution . 这与@ fgblomqvist的解决方案非常相似。 The major difference is that you do not have to recreate the table. 主要区别在于您不必重新创建表。 In essence, the following should help: 实质上,以下内容应该有所帮助:

SnapshotTable.metadata.reflect(extend_existing=True, only=['mytable'])

The unsung hero here is the extend_existing parameter. 这里的无名英雄是extend_existing参数。 It basically makes sure that the schema and other info associated with SnapshotTable are reloaded. 它基本上确保重新加载与SnapshotTable相关的模式和其他信息。 The parameter only is used here to limit how much information is retrieved. 此处only使用该参数来限制检索的信息量。 This will save you a tremendous amount of time, if you are dealing with a large database 如果您正在处理大型数据库,这将为您节省大量时间

I hope this serves a purpose in the future. 我希望这在未来有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM