如何在Frappe框架中通过外部API批量创建文档?报错求助
问题解决与批量创建+文件操作指导
一、报错原因与代码修正
1. 核心问题分析
你遇到的ModuleNotFoundError: No module named 'frappe.model'及功能异常,主要由以下原因导致:
- 自定义DocType的Python类命名不符合Frappe规范(必须用驼峰式,与DocType名称对应)
- 环境依赖缺失(
requests模块未安装) - 代码缩进错误:
new_doc.insert()在循环外,只会插入最后一条数据
2. 修正后的完整代码
假设你的DocType名称为Todo List(对应文件路径为你的自定义应用/doctype/todo_list/todo_list.py):
import frappe from frappe.model.document import Document import requests class TodoList(Document): def fetch_and_create_todos(self): doctype_name = "Todo List" # 必须与你创建的DocType名称完全一致 try: # 发起API请求并捕获HTTP错误 response = requests.get("https://jsonplaceholder.typicode.com/todos") response.raise_for_status() json_data = response.json() # 查询已存在的ID,避免重复插入 existing_ids = frappe.db.sql_list(f"""SELECT `id` FROM `tab{doctype_name}`""") # 批量创建文档 count = 0 for json_object in json_data: todo_id = json_object["id"] if todo_id not in existing_ids: new_doc = frappe.get_doc({ "doctype": doctype_name, "id": todo_id, "title": json_object["title"], "completed": json_object["completed"], }) new_doc.insert(ignore_permissions=True) count += 1 # 每100条提交一次事务,优化性能 if count % 100 == 0: frappe.db.commit() frappe.db.commit() frappe.msgprint(f"成功创建 {count} 条新待办记录") except Exception as e: frappe.log_error(f"导入失败: {str(e)}", "Todo数据导入错误") frappe.msgprint(f"导入失败: {str(e)}")
3. 环境依赖修复
Frappe默认未安装requests,需在Docker容器中执行:
# 进入Frappe容器(替换为你的容器名) docker exec -it frappe-bench-frappe-1 bash # 安装requests pip install requests
或者在自定义应用的requirements.txt中添加requests,重新构建容器。
二、批量创建注意事项
- 权限处理:后台执行时需加
ignore_permissions=True,避免权限校验报错 - 重复数据拦截:通过数据库查询已存在的ID,跳过重复项,防止数据冗余
- 事务优化:批量插入时每100条提交一次事务,避免内存占用过高
- 错误日志:用
frappe.log_error记录错误信息,方便后续排查
三、Frappe文件操作逻辑指导
如果需要处理API返回的文件(如图片、附件),可按以下流程操作:
1. 下载文件并上传到Frappe
import os import tempfile from frappe.core.doctype.file.file import File def attach_file_to_todo(todo_doc, file_url): try: # 下载文件到临时路径 response = requests.get(file_url) response.raise_for_status() # 创建临时文件存储内容 with tempfile.NamedTemporaryFile(delete=False) as tmp_file: tmp_file.write(response.content) tmp_path = tmp_file.name # 将文件上传到Frappe并关联到待办文档 file_doc = File( file_name=os.path.basename(file_url), content=response.content, is_private=False, # 设置为True则仅有权限用户可访问 attached_to_doctype="Todo List", attached_to_name=todo_doc.name ) file_doc.insert(ignore_permissions=True) frappe.db.commit() # 删除临时文件 os.unlink(tmp_path) return True except Exception as e: frappe.log_error(f"文件上传失败: {str(e)}", "Todo附件上传错误") return False
2. 文件操作关键注意点
- 大小限制:Frappe默认限制文件大小,可在站点配置文件
site_config.json中修改max_file_size参数 - 批量处理:大量文件上传需分批次执行,避免超时
- 私有文件:设置
is_private=True后,文件仅对拥有文档权限的用户开放
内容的提问来源于stack exchange,提问作者aasitvora99
相关产品推荐
相关产品推荐

