SQLAlchemy best way to define __repr__ for large tables

前端 未结 1 1004
误落风尘
误落风尘 2021-01-12 17:22

I have a bunch of tables in SQLAlchemy that I want to define __repr__.

The standard convention seems to look like this:

def __repr__(sel         


        
相关标签:
1条回答
  • 2021-01-12 18:03

    Having good __repr__ for complex objects can be incredibly useful when navigating log files and stacktraces, so it's great that you're trying to come up with a good pattern for it.

    I like to have a little helper with a default (BaseModel gets set as the model_class when initializing flask-sqlalchemy in my case).

    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)}>"
    

    Now you can keep your __repr__ methods nice and neat:

    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)
    

    Should produce something like:

    <MyModel(id=1829,user=<User(id=21, email='foo@bar.com')>,blah='hi')>

    0 讨论(0)
提交回复
热议问题