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上被忽略:另请参阅: