LoginSignup
6
5

More than 5 years have passed since last update.

Django + SQLAlchemy 環境でModelのデバッグを見やすくした話

Posted at

経緯

Python and Django 1ヶ月目の私です。Rails歴は2年ほど。
PythonのDebugってなんでこんなに見づらいのだろう。特にModel。
以下の様な表示。こんなの見て誰得。

>>> class Foo(object):
        pass
>>>
>>> repr(Foo())
'<__main__.Foo object at 0x02A74E50>'

そう思いなにか違う方法はないかネットの海を探し歩き、reprを使うと綺麗に見れる!
やった!これで 辛さから開放だ!

def __repr__(self):
    return '<Stats: description={0.description!r}, mystat={0.mystat!r}>'.format(self)

...なにこれめんどくさい。

class 1つ1つに書き込む必要がある。
一発ライブラリか何か追加して出来ないのかー??と、思うわけ。

あった。

参考: http://stackoverflow.com/a/15929677/5114776

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

if __debug__:
    # monkey-patch in useful repr() for all objects, but only in dev
    def tablerepr(self):
        return "<{}({})>".format(
            self.__class__.__name__,
            ', '.join(
                ["{}={}".format(k, repr(self.__dict__[k]))
                    for k in sorted(self.__dict__.keys())
                    if k[0] != '_']
            )
        )
    Base.__repr__ = tablerepr
>>> session.query(FooBar).get(1)
<FooBar(id=1, foo='bar', comments='foobar', hoge=1231242342341342342, fuga=datetime(2015, 5, 5, 5, 5, 5), tiger='waearsdtdygfyfguiohjohjohpp'>

しかし、この参考だけではまだまだ見づらい。
俺は機械じゃねー!人が見ても見やすいフォーマットを!それでないと意味が無い!

もっと見やすく

Base = declarative_base()

if __debug__:
    # monkey-patch in useful repr() for all objects, but only in dev
    def tab_char(max_length, target_lenght):
        tab = []
        tab_char_count = 4
        tab_count = (max_length/tab_char_count - target_lenght/tab_char_count) + 1
        for i in range(tab_count):
            tab.append('\t')
        return "".join(tab)


    def table_repr(self):
        max_length = max(map(lambda n: len(n), self.__dict__.keys()))
        return "\n<{}({})>".format(
            self.__class__.__name__,
            ', '.join(
                ["\n\t{}{}= {}".format(k, tab_char(max_length, len(k)), repr(self.__dict__[k]))
                 for k in sorted(self.__dict__.keys())
                 if k[0] != '_']
            )
        )

    Base.__repr__ = table_repr
>>> session.query(FooBar).get(1)
<FooBar(
    id                  = 1
    fooooooooo          = 'bar',
    comments            = 'foobar',
    hoge                = 1231242342341342342, 
    fuga                = datetime(2015, 5, 5, 5, 5, 5), 
    tiger               = 'waearsdtdygfyfguiohjohjohpp'>

完璧。

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5