我有一个脚本,它在我的数据库中的每个项目上运行一个函数来提取学术引文。数据库很大,因此脚本需要大约一周的时间才能运行。
在此期间,会在数据库中添加和删除项目。
数据库太大而无法完全进入内存,因此我必须通过它来处理所有项目。
有没有办法确保脚本完成后,所有项目都已处理完毕?这是一个简单的解决方案吗?到目前为止,我的研究还没有发现任何有用的东西。
PS:锁定桌子一周不是一个选择!
答案 0 :(得分:1)
我会添加一个时间戳列" modified_at"到默认为null的表。因此,可以识别任何新项目。
然后,您的脚本可以根据该列选择要处理的块。
update items
set modified_at = current_timestamp
from (
select id
from items
where modified_at is null
limit 1000 --<<< this defines the size of each "chunk" that you work on
) t
where t.id = items.id
returning items.*;
这将更新1000个尚未处理的行,并将在一个语句中返回这些行。然后,您的工作可以处理退回的项目。
需要使用modified_at = null
添加新行,并且您的脚本会在您下次运行时根据where modified_at is null
条件选择它们。
如果您在处理项目时更改项目,则需要相应地更新modified_at
。在您的脚本中,您将需要存储处理的最后一个开始。然后,您的脚本的下一次运行可以使用
where modified_at is null
or modified_at < (last script start time)
如果你只处理每个项目一次(然后再也不会),你就不需要时间戳,一个简单的布尔值(例如is_processed
)也可以。