繁体   English   中英

SqlAlchemy 创建表指定模式

[英]SqlAlchemy Create Table Specifying Schema

我想通过 SqlAlchemy 反射将表从 SQL 服务器复制到 Sqlite。

from sqlalchemy import create_engine, MetaData, Table

source_engine = create_engine(...) # create sql server engine
source_connection = source_engine.connect()
source_metadata = MetaData() # (1)

destination_engine = create_engine('sqlite:///test.db', echo=True)
destination_connection = destination_engine.connect()

Table('table_name', source_metadata, autoload=True, autoload_with=source_engine) # (2)

source_metadata.create_all(destination_engine)

以上适用于默认架构(dbo),但我想在 SQL 服务器中指定反射表的架构。

当我将 (1) 更改为source_metadata = Metadata(schema='dbo')或 (2) 更改为Table(table_name, source_metadata, autoload=True, autoload_with=source_engine, schema='dbo')我收到以下错误:

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unknown database "dbo"

我知道问题出在 sqlite 上。 当我在 SQLite Studio 中创建一个表时,如下所示,我得到了同样的错误:

CREATE TABLE dbo.table_name(...

但以下成功创建表:

CREATE TABLE [dbo.table_name](...

最后,我尝试了以下但没有成功:

destination_engine.execute("ATTACH DATABASE 'test.db' AS 'dbo'")

如何使用 SqlAlchemy 创建指定架构的表?

首先,sqlite 不支持模式,因为它们已知在其他 RDBMS 中。 为您创建[dbo.table_name]的事实就是这样 - 它是一个完整的表名,包括括号。

因此,我假设您完全放弃它就可以了。

为此,只需在调用create_all之前将其设置为None

# either specifying `schema='xxx'` on the Table() or on `Metadata()` or both will work just fine
source_metadata = MetaData(schema='xxx')
table1 = Table('table_name', source_metadata, autoload=True, autoload_with=source_engine, schema='xxx')  

# unset schema
table1.schema = None

# or if you have multiple tables, you will just have to set `.schema = None` to all of them:
for tbl in src_metadata.tables.values():
    tbl.schema = None

# now create the tables on the destination engine
source_metadata.create_all(destination_engine)

或者,如果您不能删除架构,您可以只更改带有前缀的表名:

for tbl in src_metadata.tables.values():
    tbl.name = tbl.schema + '_' + tbl.name
    tbl.schema = None

无论如何,您可能还需要修复所有 ForeignKeys ......所以它比仅仅更改架构要多得多;)


而且我担心schema可能不是将数据从一种类型数据库复制到另一种类型的最后一个问题。 可能会出现不兼容的数据类型。 如果是这样,请阅读使用与数据库无关的类型进行反射 同样使用重命名表/模式,您可能需要注意重新链接ForeignKey s、 Index等。

我们可以使用 SqlAlchemy API 中提供的 Inspector 功能来创建新表。 架构、表和相应的约束由“Inspector API”处理——

from sqlalchemy import inspect,create_engine

engine = create_engine('....')

ins=inspect(engine)

有关更多信息,请参阅以下文档: https://docs.sqlalchemy.org/en/14/core/reflection.html?highlight=inspector#inspector-inspector-inspector-gralight=inspector#

暂无
暂无

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

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