如何获取声明 Table 实例的模块的名称?

培根

我有一个像这样定义的 sqlalchemy 表

from sqlalchemy.sql.schema import Table

my_table = Table(
    "my_table",
    metadata,
    Column("my_id", BigInteger(), primary_key=True),
    ...
)

我正在尝试检查此实例以获取创建它的模块。我曾尝试使用sqlalchemy.inspect(my_table).__module__, my_table.__module__, ,inspect.getmodule(my_table)但是,所有三个都返回sqlalchemy.sql.schemaTable是定义的模块而不是定义的模块my_table

如何检索已实例化的模块的名称my_table

超级射击

您可以通过子类化来添加功能Table在 SQLAlchemy 中,Table专门覆盖Table.__init__()以使其成为无操作:

def __init__(self, *args, **kw):
    """Constructor for :class:`~.schema.Table`.
    This method is a no-op.   See the top-level
    documentation for :class:`~.schema.Table`
    for constructor arguments.
    """
    # __init__ is overridden to prevent __new__ from
    # calling the superclass constructor.

关键是它不会调用super().__init__(),因此 sqlalchemy 可以控制实例化,无论您做什么,都需要维护。

from sqlalchemy.sql.schema import Table

class MyTable(Table):

    def __init__(self, *args, **kwargs):
        self._where_am_i = __file__

my_table = MyTable(
    "my_table",
    metadata,
    Column("my_id", BigInteger(), primary_key=True)
)

在这种情况下,MyTable.__init__()仍然阻塞超类构造函数,但它也向实例添加了一个属性,该属性将是类在其中实例化的模块的名称。我特别选择了一个_where_am_i不太可能被 sqlalchemy 覆盖的晦涩属性名称 ( ) 并使用__file__返回模块的路径(但您可以根据需要进行任何设置)。

我测试过插入和选择仍然有效:

import logging
from sqlalchemy.sql import select
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
logging.basicConfig(level=logging.INFO)
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
conn = engine.connect()
conn.execute(my_table.insert(), [{"my_id": i} for i in range(1, 6)])
s = select([my_table])
result = conn.execute(s)
for row in result:
    print(row)
# (1,)
# (2,)
# (3,)
# (4,)
# (5,)

和实例化位置:

print(my_table._where_am_i)  # 53302898.py (that's the name of my module).

外部模块:

# external_module.py

from sqlalchemy_app import Base
from sqlalchemy.sql.schema import Table
from sqlalchemy import Column, BigInteger

metadata = Base.metadata

class MyTable(Table):

    def __init__(self, *args, **kwargs):
        self._where_am_i = __file__

my_table = MyTable(
    "my_table",
    metadata,
    Column("my_id", BigInteger(), primary_key=True)
)

和:

# 53302898.py

from external_module import my_table

if __name__ == '__main__':
    print(my_table._where_am_i)  # prints C:\Users\peter_000\OneDrive\git\test\external_module.py

请注意它如何返回第一个测试中的相对文件路径和外部模块测试中的绝对文件路径。你可以在这里阅读:Python __file__ 属性是绝对的还是相对的?但是您可以使该_where_am_i属性返回适合您的应用程序所需的任何内容。

编辑上述解决方案需要在形成实例的模块类进行子Table类化,否则它将固定类实例化的模块,而不是实例。如果您只想在项目中子类化一次,则需要将位置传递给构造函数。Table

这有效:

class MyTable(Table):

    def __init__(self, *args, _where_am_i=None, **kwargs):
        self._where_am_i = _where_am_i

...但是您在实例化时收到警告:

SAWarning: Can't validate argument '_where_am_i'; can't locate any SQLAlchemy dialect named '_where'.

为避免这种情况,您必须覆盖 sqlalchemy 的备用构造函数 ,去掉Table._init()location 参数,然后委托备份链:

class MyTable(Table):

    def _init(self, *args, _where_am_i=None, **kwargs):
        self._where_am_i = _where_am_i
        super()._init(*args, **kwargs)

从外部模块导入:

# 53302898.py
from external_module import MyTable

my_table = MyTable(
    "my_table",
    metadata,
    Column("my_id", BigInteger(), primary_key=True),
    _where_am_i = __file__
)

if __name__ == '__main__':
    print(my_table._where_am_i)  # 53302898.py

以上所有测试仍然通过。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Node.js从实例获取模块名称

来自分类Dev

如何获取模块的新实例

来自分类Dev

Javascript:如何获取实例名称?

来自分类Dev

如何从模块ID获取Moodle模块名称

来自分类Dev

如何从模块ID获取Modyle模块名称

来自分类Dev

如何编写每个网络名称空间中的新实例的Linux内核模块?

来自分类Dev

从模型名称获取模块名称

来自分类Dev

如何在枚举声明中获取值的名称?

来自分类Dev

获取枚举实例的名称

来自分类Dev

获取模块名称或标识

来自分类Dev

如何获得带有声明的类的Geb模块实例?

来自分类Dev

如何在JavaScript中获取实例名称?

来自分类Dev

如何获取实例名称?红宝石

来自分类Dev

如何获取Java中的实例名称?

来自分类Dev

如何从向量获取真实的类实例名称?

来自分类Dev

如何在异常中获取模块名称

来自分类Dev

如何从模块实例获取服务实例[Angular]

来自分类Dev

获取类内实例的名称

来自分类Dev

Verilog:如何实例化模块

来自分类Dev

在karaf 3.0.2中使用声明式服务时如何获取当前bundle的BundleContext实例

来自分类Dev

如何测试当前实例名称?

来自分类Dev

如何测试当前实例名称?

来自分类Dev

用“ foo = function(){...}”声明时,如何获取当前运行的函数名称?

来自分类Dev

如何在Ruby中获取Tempfile实例的名称?

来自分类常见问题

如何从T-SQL获取当前实例名称

来自分类Dev

如何从市场上获取云服务的活动实例名称?

来自分类Dev

如何获取脚本运行所在的GCE实例名称?

来自分类Dev

如何获取业务流程实例服务器名称

来自分类Dev

如何使用SimpleInjector获取特定名称空间的实例?