猿问

如何在Python中的模块级initialize()方法内动态创建类

我正在编写一个库,以使用SQLAlchemy与数据库进行通讯。我真的很喜欢SQLAlchemy的autoload_with=engine功能,该功能可以传递给Table构造函数以获取表的所有列,而无需程序员明确定义它们。


这是名为“ something”的表的基本方法:


Base = declarative_base()

engine = create_engine('mysql://user:pass@host/db_name')

table = Table('something', Base.metadata, autoload_with=engine)


class Something(Base):

    __table__ = table

但是,我们有数据库的多个版本(在不同的主机上),因此我需要在运行时将引擎作为参数传递。我讨厌在模块中编写类似这样的内容,但是我想放弃一个更好的方法:


Base = declarative_base()

Something = None   # gets defined after initialize() is called


def initialize(engine):

    table = Table('something', Base.metadata, autoload_with=engine)

    class _Something(Base):

        __table__ = table


    global Something

    Something = _Something

然后,在使用任何SQLAlchemy模型之前,客户端代码必须执行以下操作:


import custom_db_api


engine = create_engine(...)

custom_db_api.initialize(engine)

是否有更好的方法来由外部调用者处理这种模块初始化?


萧十郎
浏览 443回答 1
1回答

慕丝7291255

好了,您将必须找到某种方法将engine变量传递给custom_db_api模块。这可能有点干净...Base = declarative_base()class Something(Base):    passdef initialize(engine):    Something.__table__ = Table('something', Base.metadata, autoload_with=engine)...或者如果您可以从某些“全局”(如)中推断出正确的引擎初始化参数sys.argv,则可以使用类似的方法...import sysBase = declarative_base()if len(sys.argv) > 1 and sys.argv[1] == '--use-alt-db':    engine = create_engine('mysql://user:pass@alt_host/db_name')else:    engine = create_engine('mysql://user:pass@main_host/db_name')table = Table('something', Base.metadata, autoload_with=engine)class Something(Base):    __table__ = table有点取决于您打算如何告诉程序使用哪个DB。
随时随地看视频慕课网APP

相关分类

Python
我要回答