繁体   English   中英

如何在 SQLAlchemy 中自动映射后端不可知的 Base

[英]How to automap a backend-agnostic Base in SQLAlchemy

我正在尝试采用 Oracle 中的简单数据库模式并将其迁移到 mssql 数据库。 我还有其他方法可以做到这一点,但我首先想到的是利用 SQLAlchemy 的 automap 和 create_all 功能来几乎即时地完成它。

不幸的是,当我尝试这样做时,我遇到了一些转换错误:

输入:

from sqlalchemy.ext.automap import automap_base
from custom_connections import connect_to_oracle, connect_to_mssql

Base = automap_base()
oracle_engine = connect_to_oracle()
mssql_engine = connect_to_mssql()

Base.prepare(oracle_engine, reflect=True, schema = ‘ORACLE_MAIN_DB’)

Base.metadata.create_all(mssql_engine)

(请注意,connect_to 函数是返回 sqlalchemy 引擎的自定义函数。目前它们只返回具有基本设置的引擎。)

Output:

CompileError: (in table 'acct', column 'acctnbr'): Compiler <sqlalchemy.dialects.mssql.base.MSTypeCompiler object at 0x00000268E8FF6DA0> can't render element of type <class 'sqlalchemy.dialects.oracle.base.NUMBER'>

问题是,虽然 Sqlalchemy 在映射 Base 时将大多数类型转换为 sqlalchemy 类型,但它与 Oracle NUMBER 类型的转换不同。 我尝试了一个类似的技巧,在自动映射的基础上使用 alembic 自动生成,但 Oracle NUMBER 类型也在那里引起了问题。

考虑到它背后的所有力量,我本以为 Sqlalchemy 能够毫无问题地处理这个问题。 运行此代码时是否有我可以使用的技术或设置,这会导致它在映射基类而不是仅映射大多数类型时将所有类型转换为它们的 Sqlalchemy 等价物?

这在关于反射的 SQLAlchemy 文档中有描述:

from sqlalchemy import MetaData, Table, create_engine
from sqlalchemy import event

mysql_engine = create_engine("mysql://scott:tiger@localhost/test")
metadata_obj = MetaData()
my_mysql_table = Table("my_table", metadata_obj, autoload_with=mysql_engine)
# my_table should already exist in your db, this is the table you want to convert

@event.listens_for(metadata_obj, "column_reflect")
def genericize_datatypes(inspector, tablename, column_dict):
    column_dict["type"] = column_dict["type"].as_generic()

my_generic_table = Table("my_table", metadata_obj, autoload_with=mysql_engine)
# generic table will be a generic version of my_table
sqlite_eng = create_engine("sqlite:///test.db", echo=True)\
my_generic_table.create(sqlite_eng)

暂无
暂无

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

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