2

サイトで自動バックアップを設定しようとして問題が発生しました。問題は次のように要約されます。

Python シェルを開き、dumpdata コマンドを 2 回呼び出します。初めて機能し、2 回目は空のリストを返します。その後、以降のすべての dumpdata 呼び出しは空のリストを返します。

>>> python manage.py shell
>>> from django.core.management import call_command
>>> call_command("dumpdata")
[{"pk": 1, (...) // lots of data //
>>> call_command("dumpdata")
>>> []

再び機能させるには、Python シェルを再起動する必要があります。

編集:Django 1.4とPython 2.6を使用しています

Edit2: 私の現在の仮説は、問題がこの問題に関連しているということです: https://code.djangoproject.com/ticket/5423 - 5 年前に特定され、Django 1.5 リリース ノートによると、次のリリースで解決される予定です。マシンで実行されている 1.4 フレームワーク コードを変更せずに、この問題を回避する方法を知っている人はいますか?

Edit3: ただし、データベース全体の sql ダンプは 0.5 MB しかないため、シリアライゼーションでメモリが不足する可能性はほとんどありません。とにかく、そのような場合、明示的なエラーが発生しませんか?

Edit4: 謎が解決しました。Tomasz Gandor が正しく判断したように、問題は、シェルが 1 つのトランザクションでコマンドを実行し、コマンドの 1 つが DBError を引き起こした後、https ://code.djangoproject.com/ticket/10813 で説明されているように、それ以降の DB 呼び出しが無視されることでした。 . 最初のダンプデータ中の DB エラーが明示的に報告されなかった理由は、私には謎のままです。

4

1 に答える 1

1

djangoがトランザクションで何かを台無しにしていることがわかります。

デバッガーで簡単な例を実行しました。

# test.py
from django.core.management import call_command
call_command("dumpdata")
print "\n---"
call_command("dumpdata")
print

そしてそれを次のように呼びました:

DJANGO_SETTINGS_MODULE=settings python test.py > log.txt

log.txtが「---\n []\n」で終わった

私が見つけたデバッガーでそれを実行した後、 django.core.management.commands.dumpdata.handle() そのmodel.objects.all()の奥深くで[]を返し続けます。

model.objects.iterator()を呼び出し、例外が発生しました。

(Pdb) list(model.objects.iterator())
*** Error in argument: '(model.objects.iterator())'
(Pdb) p list(model.objects.iterator())
*** DatabaseError: DatabaseError('current transaction is aborted, commands ignored    until end of transaction block\n',)
(Pdb) 

そこで、トランザクション自体で動作するコードを一緒にハッキングしました。

# test.py version 2.0!

#!/usr/bin/env python
# from django.core.management import call_command
import django.core.management as mgmt
from django.db import transaction

''' 
try:
    import settings # Assumed to be in the same directory.
except ImportError:
    import sys
    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
    sys.exit(1)
'''

@transaction.commit_manually
def main():
    # mgmt.call_command('dumpdata', use_base_manager=True)
    mgmt.call_command('dumpdata')
    transaction.rollback()
    print
    print '---'
    print
    """ 
    mgmt._commands = None
    import sys
    reload(sys.modules['django.core.management.commands.dumpdata'])
    """
    mgmt.call_command('dumpdata')
    transaction.rollback()
    print

if __name__ == "__main__":
    main()

これにより、データベース全体が毎回吐き出されます。

于 2012-07-13T04:33:49.157 に答える