我有一个在我的服务器上运行的广泛程序。带错误的行如下所示:
result[0].update(dictionary)
result[0]
看起来像("label",{key:value,...})
所以我收到一条错误消息,指出tuple
没有update
当我将其修改为result[0][1].update(dictionary)
时,我得到了同样的错误!
然后我在上面添加了print "test"
以查看发生了什么,我得到了同样的错误,但它给了我在print语句中发生的错误。这告诉我服务器运行的代码是原始代码,而不是编辑过的代码。我尝试重启服务器。我保存了我的代码。我不明白为什么以及如何发生这种情况。可能导致此问题的原因以及如何使服务器识别出更新的版本?
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/background_task/tasks.py", line 160, in run_task
tasks.run_task(task.task_name, args, kwargs) [2/1832]
File "/usr/local/lib/python2.7/dist-packages/background_task/tasks.py", line 45, in run_task
task.task_function(*args, **kwargs)
File "/.../proj/tasks.py", line 10, in automap_predict
automap_obj.predict()
File "/.../proj/models.py", line 317, in predict
prediction = predictions[1]
File "/.../proj/models.py", line 143, in predict
#this is a recursive call
File "/.../proj/models.py", line 143, in predict
#this is a recursive call
File "/.../proj/models.py", line 127, in predict
#result[0].update(dictionary) this happens at the base case of the recursion
AttributeError: 'tuple' object has no attribute 'update'
请注意我在已注释掉的行上收到此错误。显示这不是真正运行的代码。
def view(request,param):
run_background_task(param)
return redirect("project.view.reload")
@background(schedule=0)
def run_background_task(param):
obj = MyModel.objects.get(field=param)
obj.predict()
这是创建result
的地方。我不允许显示此代码,但请注意,我确信实际代码无关紧要。它工作正常。我更改了它以进行快速更新。我收到了一个错误。然后我修复了错误,但继续得到同样的错误。我甚至回到了正在运行的旧版本,我仍然得到同样的错误。因此,此错误与此函数的内容无关。
如果我能提供更多帮助,请告诉我。
答案 0 :(得分:7)
如果您正在运行随django提供的开发服务器,即./manage.py runserver
,您不应该遇到此问题,因为它会在.py文件保存时自动重新编译。但是如果你运行wsgi说用apache服务器这是一个常见问题,但有一个非常简单的解决方案。基本上会发生什么,无论何时更改.py文件,服务器仍将使用以前编译的python文件。因此,解决方案是重新启动apache sudo service apache2 restart
(这是一种过度杀伤)或只是运行touch wsgi.py
,无论你的wsgi.py位于项目中,它都会告诉它重新编译.py文件。当然你也可以删除.pyc文件,但这太繁琐了。
修改强>
我只是注意到您正在使用@background
装饰器,这让我相信您正在使用django-background-task。如果是这种情况,您必须确保此应用程序实际上也考虑了您的代码更改,这可能不会在使用touch wsgi.py
方法重新编译python文件时自动发生。我没有这个特定应用程序的经验,但是例如使用celery,这是一个用于调度任务的更复杂的应用程序,您还必须重新启动工作程序以反映代码中的更改因为工人实际上存储了代码的腌制版本。
现在看完django-background-task应用程序(看起来就像你正在使用的应用程序)之后,理论上你不应该做任何特别的事情,但只是为了确保你能清除任何预定的任务并重新安排他们。我没有尝试,但您应该可以通过./manage.py shell
:
>>> from background_task.tasks import tasks
>>> tasks._tasks = {}
对于DBTaskRunner
来说,你甚至可能需要清除数据库:
>>> from background_task.models import Task
>>> Task.objects.all().delete()
答案 1 :(得分:1)
可能这就是你要找的东西吗?
result = (
("item1",{'key1': 'val1'}),
("item2",{'key2': 'val2'}),
)
my_dict = {
'key1': 'updated val',
'new key': 'new value'
}
pprint.pprint(result[0]) # Result: ('item1', {'key1': 'val1'})
key, dct = result[0]
dct.update(my_dict)
pprint.pprint(result) # Result: (('item1', {'key1': 'updated val', 'new key': 'new value'}), ('item2', {'key2': 'val2'}))
答案 2 :(得分:1)
该问题可能与位于服务器上项目文件夹中的已编译python文件或“.pyc”文件有关。解释python代码时会自动生成这些文件。有时,即使存在新代码并且它仍然运行旧代码,这些文件也不会被重新编译。
您可以通过pip安装“django-extensions”,它附带了一个方便的manage.py命令,可以帮助您清除这些文件:
python manage.py clean_pyc
如果这不起作用,那么你需要重新启动运行代码的wsgi服务器,因为python代码在内存中。
答案 3 :(得分:1)
如果代码未更新,解决方案将取决于您为应用程序提供服务的方式。如果您使用./manage.py runserver,则不应该遇到问题。如果重新启动服务器,如果使用apache + mod_python,则应重新加载代码。
但我认为你没有做其中任何一个,因为你还有这个问题。如果您使用uWSGI或gunicorn,它们在与服务器不同的进程中运行,则需要单独重新启动它们。 uWSGI也可以设置为每次设置文件更改时重新加载应用程序,所以通常我只需要调用touch myapp.ini
来重新加载代码。
答案 4 :(得分:1)
基本上会发生什么,无论何时更改.py文件,服务器仍将使用以前编译的python文件。所以解决方案是重启apache sudo service apache2 restart(这是一个过度杀手)或者只是运行touch wsgi.py,无论你的wsgi.py位于项目中,它都会告诉它重新编译.py文件。当然你也可以删除.pyc文件,但这太繁琐了。
你正在使用@background装饰器,这让我相信你正在使用django-background-task。如果是这种情况,您将必须确保此应用程序实际上也考虑了您的代码更改,这可能不会在使用touch wsgi.py方法重新编译python文件时自动发生。我没有使用这个特定应用程序的经验,但是例如使用芹菜,这是一个用于调度任务的更复杂的应用程序,您还必须重新启动工作程序以反映代码中的更改,因为工作人员实际存储了腌制版的代码。
现在看完django-background-task应用程序(看起来就像你正在使用的那个),理论上你不必做任何特别的事情,但只是为了确保你能清除任何计划的任务和重新安排他们。
答案 5 :(得分:0)
看来你的result
并不像你想象的那样,我只是使用了与你描述的格式相同的格式,你看它有效。您应该检查它返回正确数据的功能。
>>> a = (('label', {'k':'3'}),)
>>> print (a[0])
('label', {'k': '3'})
>>> a[0][1].update({'k':'6'})
>>> print (a[0])
('label', {'k': '6'})
>>>
仅供参考,如您所见Here,元组是不可变的序列类型,因此它们不支持更新,这就是为什么它们不需要定义update
函数的原因。
如果要更新本身是元组的result[0]
(如所显示的错误消息所清楚),则必须使用更新的实体创建新元组。