Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django drf请求似乎需要很长时间才能重新启动_Django_Django Rest Framework - Fatal编程技术网

Django drf请求似乎需要很长时间才能重新启动

Django drf请求似乎需要很长时间才能重新启动,django,django-rest-framework,Django,Django Rest Framework,我将Django与DRF一起使用,我有一个视图集,它将信息写入csv文件,然后将链接发送给用户 当检索到的数据不是太大时,该函数可以正常工作,因此当响应时间合理时,一切正常 问题是请求需要更长的时间。看起来它只是从请求调用中自行重新启动 def get_operations(self, request): logger.info("Starting export request...") #[...business logic to retrive the data

我将Django与DRF一起使用,我有一个视图集,它将信息写入csv文件,然后将链接发送给用户

当检索到的数据不是太大时,该函数可以正常工作,因此当响应时间合理时,一切正常

问题是请求需要更长的时间。看起来它只是从请求调用中自行重新启动

    def get_operations(self, request):
        logger.info("Starting export request...")
   #[...business logic to retrive the data ...]
        file_url = settings.MEDIA_PREFIX_PATH + file_path
        logger.info("Saving response in %s", file_absolute_path)
        f = open(file_absolute_path, "w+")
        all_operations = operations.all()
        i = 0
        for operation in all_operations:
            i = i + 1
            #code to show progress in the log
            if (i / len(all_operations)*1000) % 5 == 0:
                logger.info("Progress:  %d ", (i / len(all_operations)*100))

            f.write("%s,%d,%d,%d,%s,%s\n" % (operation.datetime, operation.amount, operation.field2, operation.field3, operation.field5, operation.field6))
        logger.info("Response saved, sending link %s", file_url)
        return Response(file_url)
在日志中,这是我得到的

INFO 2018-11-26 11:23:33,525 Starting export request...
INFO 2018-11-26 11:23:34,223 Response retrieved : 17010 records
INFO 2018-11-26 11:23:34,225 Saving response in /tmp/generated_csv/1543231414.2250094.csv
INFO 2018-11-26 11:23:42,825 Progress:  10 
INFO 2018-11-26 11:23:51,161 Progress:  20 
INFO 2018-11-26 11:23:59,072 Progress:  30 
INFO 2018-11-26 11:24:07,694 Starting export request...
INFO 2018-11-26 11:24:08,346 Response retrieved : 17010 records
INFO 2018-11-26 11:24:08,348 Saving response in /tmp/generated_csv/1543231448.3486001.csv
INFO 2018-11-26 11:24:16,653 Progress:  10 
INFO 2018-11-26 11:24:24,271 Progress:  20 
INFO 2018-11-26 11:24:32,248 Progress:  30 
INFO 2018-11-26 11:24:42,573 Starting export request...
INFO 2018-11-26 11:24:44,101 Response retrieved : 17010 records
INFO 2018-11-26 11:24:44,109 Saving response in /tmp/generated_csv/1543231484.1097722.csv
INFO 2018-11-26 11:24:55,092 Progress:  10 
INFO 2018-11-26 11:25:04,131 Progress:  20 
INFO 2018-11-26 11:25:11,242 Progress:  30 
INFO 2018-11-26 11:25:16,801 Starting export request...
INFO 2018-11-26 11:25:17,499 Response retrieved : 17010 records
INFO 2018-11-26 11:25:17,501 Saving response in /tmp/generated_csv/1543231517.5013359.csv
我确信这个问题不是来自客户端,因为我也曾与邮递员一起尝试过

我只是不明白是什么导致请求被单独调用


谢谢

我猜这不是Django或DRF的问题,很可能是gunicorn或您用来服务Django的东西的问题。因此,不要在同步模式下执行这些大文件操作,而是尝试任何异步进程。例如:

import threading 

...

def process_file(self, file_absolute_path, all_operations):
        f = open(file_absolute_path, "w+")
        i = 0
        for operation in all_operations:
            i = i + 1
            # it will be visible in your logger file, so you can see the progress
            if (i / len(all_operations)*1000) % 5 == 0:
                logger.info("Progress:  %d ", (i / len(all_operations)*100))
                f.write("%s,%d,%d,%d,%s,%s\n" % (operation.datetime, operation.amount, operation.field2, operation.field3, operation.field5, operation.field6))

def get_operations(self, request):
    logger.info("Starting export request...")
    all_operations = operations.all()
    file_url = settings.MEDIA_PREFIX_PATH + file_path
    t = threading.Thread(target=self.process_file,
                         args=(file_absolute_path, all_operations))
    t.start()
    logger.info("Saving response in %s", file_absolute_path)
    logger.info("Response saved, sending link %s", file_url)
    return Response(file_url)

这里我给出了使用Python的示例。但您也可以将其用于此目的(这是一个更好的解决方案)。

不幸的是,我们无法帮助您解决当前形式的问题。尝试查看从web服务器日志(apache或nginx)中获得的信息。他们可能会再次尝试处理该请求,或者您的客户会这样做。尝试调整他们的超时时间。如果请求未在配置的时间范围内得到处理,有些人会关闭连接。不知道是什么导致重新启动,但您肯定需要优化此过程。太慢了。我的猜测是“进度记录”对性能有很大的影响。我在其中一个项目中使用了类似的方法,其中大约100万条记录被写入CSV,整个过程所需的时间大约相当于您30%的17k条记录所需的时间。我也在分块查询,但这与17k记录无关。@Linovia,我使用的是gunicorn,如果这是常见的,我会尝试在gunicorn中搜索there@Borut进度日志只是为了调试这个问题而添加的,即使没有它,它也会发生,有没有其他原因导致写得慢?我明白了,@DanyY。尝试使用“with”重写CSV写入过程。通过使用“with”,可以预测数据何时会保存到文件中。谢谢,我会检查这一点,我只会遇到一个问题,在异步任务完成之前,我发送的链接是空的。也许我应该发送其他请求,以检查文件是否已完成,以发回链接?这方面有没有最佳做法?您可以稍后发送带有该链接的电子邮件。只需向用户发送一条消息,他的链接很快就会被发送。