SQLAlchemy 为大型表定义 __repr__ 的最佳方法

Posted

技术标签:

【中文标题】SQLAlchemy 为大型表定义 __repr__ 的最佳方法【英文标题】:SQLAlchemy best way to define __repr__ for large tables 【发布时间】:2019-09-06 21:08:14 【问题描述】:

我在 SQLAlchemy 中有一堆表,我想定义 __repr__

标准约定看起来像这样:

def __repr__(self):
    return "<TableName(id='%s')>" % self.id

这对小桌子来说很好。但是,我有 40 多列的表。 有没有更好的方法来构造__repr__,这样我就不用手动输入大量字符串了?

我存放所有表格的文件名为models.py。我想到的一个解决方案是在models.py 中创建一个方法_create_repr_string,该方法负责自动生成字符串以供__repr__ 返回。我想知道是否有更标准的方法来创建__repr__

【问题讨论】:

您好,我最近回答了一个类似的问题:***.com/a/54034230/6560549 看看这个ReprMixin,你可以添加到你的基类中:github.com/absent1706/sqlalchemy-mixins#beauty-repr 【参考方案1】:

在导航日志文件和堆栈跟踪时,为复杂对象提供良好的 __repr__ 非常有用,因此您尝试为它提出一个好的模式真是太好了。

我喜欢有一个默认的小帮手(在我的例子中,当初始化 flask-sqlalchemy 时,BaseModel 被设置为 model_class)。

import typing
import sqlalchemy as sa

class BaseModel(Model):

    def __repr__(self) -> str:
        return self._repr(id=self.id)

    def _repr(self, **fields: typing.Dict[str, typing.Any]) -> str:
        '''
        Helper for __repr__
        '''
        field_strings = []
        at_least_one_attached_attribute = False
        for key, field in fields.items():
            try:
                field_strings.append(f'key=field!r')
            except sa.orm.exc.DetachedInstanceError:
                field_strings.append(f'key=DetachedInstanceError')
            else:
                at_least_one_attached_attribute = True
        if at_least_one_attached_attribute:
            return f"<self.__class__.__name__(','.join(field_strings))>"
        return f"<self.__class__.__name__ id(self)>"

现在您可以让您的 __repr__ 方法保持整洁:

class MyModel(db.Model):

    def __repr__(self):
        # easy to override, and it'll honor __repr__ in foreign relationships
        return self._repr(id=self.id,
                          user=self.user,
                          blah=self.blah)

应该产生类似的东西:

&lt;MyModel(id=1829,user=&lt;User(id=21, email='foo@bar.com')&gt;,blah='hi')&gt;

【讨论】:

我喜欢这种方法的可定制性,谢谢! 我想在烧瓶中实现你的助手,但遇到了以下错误:sqlalchemy.exc.ArgumentError: Mapper mapped class BaseModel-&gt;base_model could not assemble any primary key columns for mapped table 'base_model' 是否有适合初学者的解释如何在不遇到此错误的情况下实现你的助手? @p6l-richard 从常用的sqlalchemy.ext.declarative.declarative_base() Stephen Fuhry 编写的BaseModel 类继承你的类。 BaseModel 本身不需要继承自 Model - 它可以是独立的。

以上是关于SQLAlchemy 为大型表定义 __repr__ 的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

我可以为类而不是实例定义 __repr__ 吗? [复制]

SQLAlchemy 动态/编程更新表定义

为自己定义每个python类添加__repr__和__str__

如何使用 SWIG 为 C++ 类提供 Python __repr__()

如何为函数本身设置 repr? [复制]

SQLAlchemy 声明式:定义触发器和索引 (Postgres 9)