Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.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在queryset上循环时,db读取何时发生?_Django_Sqlite_For Loop_Django Orm - Fatal编程技术网

Django在queryset上循环时,db读取何时发生?

Django在queryset上循环时,db读取何时发生?,django,sqlite,for-loop,django-orm,Django,Sqlite,For Loop,Django Orm,我正在我的数据库中循环并更新我所有的公司对象 for company in Company.objects.filter(updated=False): driver.get(company.company_url) company.adress = driver.find_element_by_id("address").text company.visited = True company.save() 我的问题是它花费的时间太长,所以我想运行同一代

我正在我的数据库中循环并更新我所有的
公司
对象

for company in Company.objects.filter(updated=False):
    driver.get(company.company_url)
    company.adress = driver.find_element_by_id("address").text
    company.visited = True    
    company.save()
我的问题是它花费的时间太长,所以我想运行同一代码的另一个实例,但我很好奇实际的db读取何时发生。如果在该循环运行时,
company.visitored
get更改为
True
,该循环是否仍将访问该公司?如果我为访问的
添加了第二个检查怎么办?如果第一个实例无法识别第二个实例的工作,我不想启动第二个循环:

for company in Company.objects.filter(updated=False):
    if company.visited:
        continue
    driver.get(company.company_url)
    company.adress = driver.find_element_by_id("address").text
    company.visited = True    
    company.save()

Company.objects.filter(updated=False)
转换为普通SQL查询:

SELECT * FROM appName_company WHERE updated is false
当您开始遍历
Company
对象时,将执行此SQL查询。它只执行一次。第二台服务器将无法识别第一台服务器的工作,因为它们都将通过相同的
公司
对象

for company in Company.objects.filter(updated=False):
    driver.get(company.company_url)
    company.adress = driver.find_element_by_id("address").text
    company.visited = True    
    company.save()
使用原子事务锁定行以避免争用条件,并
为\u update()选择\u

您可以在多台服务器上运行此代码。每个
公司将只处理一次

如果您需要定期执行此代码,我强烈建议您使用芹菜。每个公司分配一个任务,让多个工人并行工作:

from celery import shared_task

@shared_task
def dispatch_tasks():
    for company in Company.objects.filter(updated=False):
        process_company.delay(company.id)

@shared_task
@transaction.atomic
def process_company(company_id):
    company = Company.objects.select_for_update().get(id=company_id)
    if company.visited:
        continue
    driver.get(company.company_url)
    company.adress = driver.find_element_by_id("address").text
    company.visited = True    
    company.save()


编辑:哦,我看到你用sqlite标记了这个问题。我建议切换到PostgreSQL,因为SQLite在并发性方面非常糟糕。我的答案应该适用于SQlite,但锁可能会减慢数据库的运行速度。

此代码是在视图、芹菜任务或其他地方执行的吗?此代码是从
manage.py shell启动的。
select\u for\u update()
在SQlite上被忽略:另请参阅: