Django:有没有办法有效地批量 get_or_create()
Django: Is there a way to effienctly bulk get_or_create()
我需要导入论文和作者的数据库(以 JSON 格式给出)。
数据库非常大(1.94 亿个条目)所以我不得不使用 django 的 bulk_create() 方法。
为了第一次加载作者,我使用了以下脚本:
def load_authors(paper_json_entries: List[Dict[str, any]]):
authors: List[Author] = []
for paper_json in paper_json_entries:
for author_json in paper_json['authors']:
# len != 0 is needed as a few authors dont have a id
if len(author_json['ids']) and not Author.objects.filter(author_id=author_json['ids'][0]).exists():
authors.append(Author(author_id=author_json['ids'][0], name=author_json['name']))
Author.objects.bulk_create(set(authors))
但是,这太慢了。
瓶颈是这个查询:
and not Author.objects.filter(author_id=author_json['ids'][0]).exists():
不幸的是,我必须进行此查询,因为一个作者当然可以写多篇论文,否则会出现键冲突。
有没有一种方法可以使用 bulk_create 有效地实现类似于正常 get_or_create()
的东西?
要避免使用现有唯一键创建条目,您可以启用 ignore_conflicts
参数:
def load_authors(paper_json_entries: List[Dict[str, any]]):
Author.objects.bulk_create(
(
Author(author_id=author_json['ids'][0], name=author_json['name'])
for paper_json in paper_json_entries
for author_json in paper_json['authors']
),
ignore_conflicts=True
)
我需要导入论文和作者的数据库(以 JSON 格式给出)。 数据库非常大(1.94 亿个条目)所以我不得不使用 django 的 bulk_create() 方法。
为了第一次加载作者,我使用了以下脚本:
def load_authors(paper_json_entries: List[Dict[str, any]]):
authors: List[Author] = []
for paper_json in paper_json_entries:
for author_json in paper_json['authors']:
# len != 0 is needed as a few authors dont have a id
if len(author_json['ids']) and not Author.objects.filter(author_id=author_json['ids'][0]).exists():
authors.append(Author(author_id=author_json['ids'][0], name=author_json['name']))
Author.objects.bulk_create(set(authors))
但是,这太慢了。 瓶颈是这个查询:
and not Author.objects.filter(author_id=author_json['ids'][0]).exists():
不幸的是,我必须进行此查询,因为一个作者当然可以写多篇论文,否则会出现键冲突。
有没有一种方法可以使用 bulk_create 有效地实现类似于正常 get_or_create()
的东西?
要避免使用现有唯一键创建条目,您可以启用 ignore_conflicts
参数:
def load_authors(paper_json_entries: List[Dict[str, any]]):
Author.objects.bulk_create(
(
Author(author_id=author_json['ids'][0], name=author_json['name'])
for paper_json in paper_json_entries
for author_json in paper_json['authors']
),
ignore_conflicts=True
)