Firestore - 递归复制文档及其所有子集合/文档

问题描述

我们将 Google 的 Firestore 用于嵌入式机器配置数据。由于此数据控制可配置的页面流和许多其他内容,因此它被分成许多子集合。在这个系统中,每台机器都有自己的顶级文档。然而,当我们将机器添加到机群时需要很长时间,因为我们必须手动复制多个文档中的所有这些数据。有谁知道如何在 Python 中递归复制 Firestore 文档、所有它的子集合、它们的文档、子集合等。您将有一个顶级文档引用以及新顶级文档的名称

解决方法

您可以使用这样的方法来递归地从一个集合读取和写入另一个集合:

def read_recursive(
    source: firestore.CollectionReference,target: firestore.CollectionReference,batch: firestore.WriteBatch,) -> None:
    global batch_nr

    for source_doc_ref in source:
        document_data = source_doc_ref.get().to_dict()
        target_doc_ref = target.document(source_doc_ref.id)
        if batch_nr == 500:
            log.info("commiting %s batched operations..." % batch_nr)
            batch.commit()
            batch_nr = 0
        batch.set(
            reference=target_doc_ref,document_data=document_data,merge=False,)
        batch_nr += 1
        for source_coll_ref in source_doc_ref.collections():
            target_coll_ref = target_doc_ref.collection(source_coll_ref.id)
            read_recursive(
                source=source_coll_ref.list_documents(),target=target_coll_ref,batch=batch,)

batch = db_client.batch()
read_recursive(
    source=db_client.collection("src_collection_name"),target=db_client.collection("target_collection_name"),)
batch.commit()

分批写入,这节省了大量时间(在我的例子中,它完成的时间比 set 快了一半)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...