※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。


【Wagtail】PathOverflowの解決方法

web開発 オーバーフロー サーバー開発 バグ wagtail

投稿日:2020年10月19日

このエントリーをはてなブックマークに追加
wagtailのPageモデルはpathの管理方法が独特で、間違ったforループなどでPageの保存などを行うとPathがOverFlowしてしまうことがあります。この記事ではPathOverFlowの解決方法について自分の例を合わせて解説しています。

はじめに

発生したエラー

今回発生したエラーはWagtailで新しくページを作成しようとした際におきました。

ターミナル
Internal Server Error: /09dy80226/pages/add/blog/blogpage/95/
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.6/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/wagtail/admin/urls/__init__.py", line 102, in wrapper
    return view_func(request, *args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/wagtail/admin/decorators.py", line 34, in decorated_view
    return view_func(request, *args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/wagtail/admin/views/pages.py", line 233, in create
    parent_page.add_child(instance=page)
  File "/usr/local/lib/python3.6/site-packages/treebeard/mp_tree.py", line 1013, in add_child
    return MP_AddChildHandler(self, **kwargs).process()
  File "/usr/local/lib/python3.6/site-packages/treebeard/mp_tree.py", line 387, in process
    newobj.path = self.node.get_last_child()._inc_path()
  File "/usr/local/lib/python3.6/site-packages/treebeard/mp_tree.py", line 1114, in _inc_path
    raise PathOverflow(_("Path Overflow from: '%s'" % (self.path, )))
treebeard.exceptions.PathOverflow: Path Overflow from: '0001000200050004ZZZZ'

バグの内容的にpathがオーバーフロー、つまり許容できる最大値を超えてしまったようです。自分のコードに思い当たるforループがあったため、とりあえずその部分を修正したのですが、

問題は解決せずページを保存しようとするとバグは発生しつづけました。

エラーの原因

エラーの原因はStackTraceに表示された通りPathがオーバーフローしていることが原因です。しかし、このオーバーフローは今保存しているページではなく前回保存したページで起きています。

Wagtailでは新しく作成するPageのpathを前回作成したPageのpathをインクリメントして生成するのですが、その値が最大値までいってしまったため、pathの生成に失敗しているのです。StackTraceで指定されたパスは'0001000200050004ZZZZ'で最後のZZZZがオーバーフローしていることがわかります。

ページを何十万も作成してこのエラーが出た場合には、もう新しくDBを作るしかありませんが、今回は単純に自分のforループのミスなのでなんとか解決できそうです。


解決方法

解決方法としては以下の流れになります。

  • 問題が起きているページを特定
  • 問題が起きているページのpathを正しいものに修正

今回はDjangoのshellから解決します。

ターミナル
python manage.py shell
Python 3.6.9 (default, Aug 14 2019, 13:02:21) 
[GCC 6.3.0 20170516] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from blog.models import BlogPage
>>> page = BlogPage.objects.get(path="0001000200050004ZZZZ")
>>> blog_pages = BlogPage.objects.all().order_by("-created")
>>> blog_pages[0].path
'0001000200050004ZZZZ'
>>> blog_pages[1].path
'0001000200050004000A'
>>> page.path="0001000200050004000B"
>>> page.save()

簡単に解説します。

まずはpage = BlogPage.objects.get(path="0001000200050004ZZZZ")で問題のあるPageインスタンスを取得します。ここでpathとして指定している値はエラーで指定された値です。

次にBlogPage.objects.all().order_by("-created")で作成日時順に並べたページを取得しています。自分はPageの作成日時をDateTimeFieldcreatedという名前のfieldで設定していますが、このfieldがない場合には-idで並べても良いでしょう。

blog_pages[0].pathで直前に作成したページに問題があることが確認できました。

ということで問題が起きたページのさらに一つ前のページのpathを、blog_pages[1].pathで確認しています。パスがオーバーフローしたことを考えるとpathは36進数のようです。そのため、0001000200050004000Aの次の値、0001000200050004000Bpathとして設定し保存しました。

これで解決です。

このエントリーをはてなブックマークに追加


関連記事

記事へのコメント