尝试在我的网站上设置自动备份时遇到了问题。问题归结为以下原因。

我打开Python Shell,然后两次调用dumpdata命令。它第一次工作,第二次返回空列表。之后,所有进一步的dumpdata调用将返回空列表:

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


为了使其再次工作,我需要重新启动python shell。

编辑:我使用Django 1.4和Python 2.6

Edit2:我当前的假设是该问题与以下问题有关:https://code.djangoproject.com/ticket/5423-5年前确定,根据Django 1.5发行说明,将在下一发行版中解决。是否有人知道如何解决此问题而不改变在计算机上运行的1.4框架代码?

Edit3:但是整个数据库的sql dump只有0.5 MB,这使得序列化用尽内存的可能性很小。无论如何,在这种情况下我不会得到显式错误吗?

Edit4:神秘感解决了。正如Tomasz Gandor正确确定的那样,问题在于shell在一个事务中执行了命令,并且其中一个命令导致DBError之后,进一步的DB调用将被忽略,如下所述:https://code.djangoproject.com/ticket/10813。为什么没有明确报告第一个dumpdata期间的DB错误仍然是我的一个谜。

最佳答案

我看到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()


每次都会吐出整个数据库!

10-06 11:18