我有一个 Django 应用程序,在管理员中有一个视图,允许员工用户上传一个 csv,然后将其传递给一个脚本,该脚本从资料中构建和更新数据库中的项目。视图在新执行绪中运行脚本,然后回传“上传开始”成功讯息。
应用程序/产品/admin.py
from threading import Thread
# ...
from apps.products.scripts import update_products_from_csv
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
# normal ModelAdmin stuff
def upload_csv(self, request):
if request.method == 'POST':
csv_file = request.FILES['csv_file']
t = Thread(target=update_products_from_csv.run, args=[csv_file])
t.start()
messages.success(request, 'Upload started')
return HttpResponseRedirect(reverse('admin:products_product_changelist'))
应用程序/产品/脚本/update_products_from_csv.py
import csv
import threading
from time import time
# ...
def run(upload_file):
# print statements just here for debugging
print('Update script running', threading.currentThread())
start_time = time()
print(start_time)
decoded_file = upload_file.read().decode('utf-8').splitlines()
csv_data = [d for d in csv.DictReader(decoded_file)]
print(len(csv_data))
for i, row in enumerate(csv_data):
if i % 500 == 0:
print(i, time() - start_time)
# code that checks if item needs to be created or updated and logs accordingly
print('Finished', time() - start_time)
在开发中,这作业正常。“上传开始”讯息几乎立即出现在浏览器中,并在控制台中打印它在 Thread-3 或 Thread-5 或其他任何东西上启动,然后执行所有其他打印陈述句。完成后,我可以查询 EntryLog 模型并确认它进行了更改。
当我将它推送到 Heroku 时,我仍然会立即在浏览器中收到“上传开始”讯息,但是当我查看日志时,它打印的是 Thread-1 而不是 Thread-[任何其他数字]。之后我看到 start_time 打印陈述句执行,但之后回应开始并且没有其他打印陈述句运行。过了一会儿,我查询了 EntryLog 模型,但没有进行任何更改。
从我读过的内容来看,听起来我应该能够像在本地一样在 Heroku 上使用执行绪,但似乎它是在主执行绪中执行脚本,然后在回应开始时默默地杀死它。
uj5u.com热心网友回复:
事实证明 Heroku 实际上打开了一个新执行绪就好了。当我打电话时它显示 Thread-1print(threading.currentThread())
是一条红鲱鱼。在我的开发环境 (Windows) 中,生成的执行绪总是打印 Thread-[number 大于 1],但是使用我确信执行完成的简单执行绪的进一步测验总是在 Heroku 环境中打印 Thread-1。Windows 与 Linux 上的库功能可能存在差异?(这是我第一次使用执行绪库,如果我遗漏了一些明显的东西,请道歉。)
实际问题似乎是我正在阅读 csv 档案的地方。很多打印陈述句后来我将其缩小到所有停止运行的确切行。我尝试了一个简单的测验,只是在一个新执行绪中读取一个 txt 档案并得到了相同的结果。没有抛出任何错误或任何东西,在那之后什么也没有。我将读取和解码档案的代码移动到主执行绪的视图中,然后将提取的资料传递给新执行绪,然后一切正常。
0 评论