如何用Python脚本读取CSV动态创建指定名称的Firestore文档?
问题场景
我有一个.csv文件,示例内容如下:
record-1a, record-1b, record-1c, document-name-1 record-2a, record-2b, record-2c, document-name-2
需求是运行Python脚本后,根据CSV文件的行数自动创建对应数量的Firestore文档,文档名称使用每行第4列的document-name-N字段值。
当前编写的实现代码如下:
import firebase_admin from firebase_admin import credentials from firebase_admin import firestore from array import array import csv cred = credentials.Certificate('firebase-sdk.json') with open('foo/bar/file.csv', 'r', newline='', encoding="utf8") as file: reader = csv.reader(file) data = [] for row in reader: data.append(row) firebase_admin.initialize_app(cred) db = firestore.client() doc_ref = db.collection('collectionname').document(row[3]) for item in data: doc_ref.set({ 'someArray': [], 'column1': item[0], 'column2': item[1], 'column3': item[2] })
查阅Firestore官方事务管理相关文档后仍未找到可行解决方案,现有代码无法为每行CSV数据创建独立命名的文档。
问题原因
代码存在两个核心错误:
- 文档引用
doc_ref是在循环外定义的,定义时用到的row[3]是读取CSV阶段最后一行的第4列值,整个循环过程中doc_ref始终指向同一个文档,所有写入操作都会覆盖这同一个文档,不会生成多个独立文档。 - 导入了无用的
array模块,代码中没有用到相关逻辑。
修正方案
把文档引用的定义移到遍历数据的循环内部,每遍历一行数据就用当前行的第4列值生成对应的文档引用,再执行写入操作即可。修正后的完整代码如下:
import firebase_admin from firebase_admin import credentials from firebase_admin import firestore import csv # 初始化Firebase cred = credentials.Certificate('firebase-sdk.json') firebase_admin.initialize_app(cred) db = firestore.client() # 读取并逐行处理CSV文件 with open('foo/bar/file.csv', 'r', newline='', encoding="utf8") as file: reader = csv.reader(file) for row in reader: # 跳过CSV中可能存在的空行 if not row: continue # 用当前行第4列作为文档ID生成文档引用,索引从0开始,第4列对应索引3 doc_ref = db.collection('collectionname').document(row[3].strip()) # 写入当前行对应的数据 doc_ref.set({ 'someArray': [], 'column1': row[0].strip(), 'column2': row[1].strip(), 'column3': row[2].strip() })
注:代码中添加的
.strip()是为了去掉CSV字段值前后可能附带的空格,避免文档ID或者字段值出现多余空白字符,如果你的CSV数据本身没有前后空格可以直接去掉该方法调用。
如果CSV数据量较大,也可以使用批量写入的方式提升执行效率,Firestore单次批量操作最多支持500个文档:
import firebase_admin from firebase_admin import credentials from firebase_admin import firestore import csv cred = credentials.Certificate('firebase-sdk.json') firebase_admin.initialize_app(cred) db = firestore.client() batch = db.batch() batch_count = 0 BATCH_UPPER_LIMIT = 500 with open('foo/bar/file.csv', 'r', newline='', encoding="utf8") as file: reader = csv.reader(file) for row in reader: if not row: continue doc_ref = db.collection('collectionname').document(row[3].strip()) batch.set(doc_ref, { 'someArray': [], 'column1': row[0].strip(), 'column2': row[1].strip(), 'column3': row[2].strip() }) batch_count += 1 # 达到批量操作上限后立即提交,重新开启新的写入批次 if batch_count == BATCH_UPPER_LIMIT: batch.commit() batch = db.batch() batch_count = 0 # 提交最后不足500条的剩余数据 if batch_count > 0: batch.commit()
内容的提问来源于stack exchange,提问作者zeerk
相关产品推荐
相关产品推荐

