为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

萧十郎 2021-03-07 12:09:24
我正在编写一个库,以使用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 calleddef initialize(engine):    table = Table('something', Base.metadata, autoload_with=engine)    class _Something(Base):        __table__ = table    global Something    Something = _Something然后,在使用任何SQLAlchemy模型之前,客户端代码必须执行以下操作:import custom_db_apiengine = create_engine(...)custom_db_api.initialize(engine)是否有更好的方法来由外部调用者处理这种模块初始化?
查看完整描述

1 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

好了,您将必须找到某种方法将engine变量传递给custom_db_api模块。这可能有点干净...


Base = declarative_base()


class Something(Base):

    pass


def initialize(engine):

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

...或者如果您可以从某些“全局”(如)中推断出正确的引擎初始化参数sys.argv,则可以使用类似的方法...


import sys


Base = 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。


查看完整回答
反对 回复 2021-03-29
  • 1 回答
  • 0 关注
  • 442 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号