批量数据导入指南

当导入非常大的数据集(例如超过 5,000 个文档)时,建议使用命令行工具 bench data-import,而不是使用 Web 界面。这种方法可以避免 Web 请求超时,并确保导入过程更加可靠。

示例命令:

bench --site test.erpnext.com data-import ~/Downloads/Activity_Type.csv

命令帮助

bench data-import --help

命令用法:

bench data-import [OPTIONS]

此命令允许您从 CSV 或 XLSX 文件批量导入文档到您的站点。

选项:

选项 说明
--file FILE 导入文件的路径(.csv, .xlsx)。请注意,相对路径将从“sites”目录解析 [必填]
--doctype TEXT 要导入的目标 DocType [必填]
--type [Insert\|Update] 插入新记录或更新现有记录
--submit-after-import 导入后提交文档
--mute-emails 导入期间静默邮件通知
--help 显示此消息并退出。

注意:

  • 如果文件路径作为位置参数提供,则可以省略 --file 选项。

使用数据迁移工具

数据迁移工具是在 Frappe Framework 第 9 版中引入的。

数据迁移工具旨在抽象远程数据源与 DocType 之间的所有数据同步操作。它是基于 Frappe 的网站与远程数据源之间的中间层。

为了理解这个工具,让我们创建一个连接器,将 ERPNext 物料推送到一个名为 Atlas 的虚拟服务中。

数据迁移计划

数据迁移计划封装了一组映射。

让我们创建一个新的 数据迁移计划。将计划名称设置为“Atlas 同步”。我们还需要在映射子表中添加映射。

数据迁移映射

数据迁移映射是一组规则,用于指定字段到字段的映射关系。

创建一个新的 数据迁移映射。将其命名为“物料到 Atlas 物料”。

要定义映射,我们需要输入一些值来定义本地和远程数据的结构。

  1. 远程对象名称:用于标识远程对象的名称,例如 Atlas 物料
  2. 远程主键:这是 Atlas 物料的主键名称,例如 id
  3. 本地 DocType:用于同步的 DocType,例如物料
  4. 映射类型:映射类型可以是“推送”或“拉取”,取决于数据是要映射到远程还是本地。也可以是“同步”,它将在单个周期内同时执行推送和拉取操作。
  5. 页长度:这定义了同步的批处理大小。

指定字段映射:

字段映射最基本的形式是指定远程和本地对象的字段名称。但是,如果映射是单向的(推送或拉取),则源字段名称也可以采用带引号的字面值(例如 "GadgetTech")和 eval 语句(例如 "eval:frappe.db.get_value('Company', 'Gadget Tech', 'default_currency')")。例如,在推送映射的情况下,本地字段名称可以设置为带引号的字符串或 eval 表达式,而不是本地 doctype 中的字段名称。(这在同步映射中是不可能的,因为在同步映射中,本地和远程字段名称在某个时刻都充当目标位置,因此不能是字面值)。

让我们添加字段映射并保存:

我们现在可以将“物料到 Atlas 物料”映射添加到我们的数据迁移计划中并保存。

通过前置和后置处理增加额外的控制层:

数据迁移通常除了字段间的一对一映射之外,还涉及更多步骤。对于添加到计划中的数据迁移映射,会在该计划指定的模块中生成一个映射模块。

在我们的案例中,在 Integrations(“Atlas 同步”计划的模块)中的 data_migration_mapping 目录下创建了一个 item_to_atlas_item 模块。

您可以实现 pre_process(接收源文档)和 post_process(接收源文档和目标文档,以及任何附加参数)方法,以扩展映射过程。以下是一些可能操作的示例:

数据迁移连接器

现在,要连接到远程源,我们需要创建一个 数据迁移连接器。

我们目前只有两种连接器类型,让我们在数据迁移连接器 DocType 中添加另一种连接器类型。

现在,让我们创建一个新的数据迁移连接器。

如您所见,我们选择了连接器类型为 Atlas。我们还为我们的 Atlas 实例添加了主机名、用户名和密码,以便进行身份验证。

现在,我们需要为我们的连接器编写代码,以便我们能够实际推送数据。

在 frappe/data_migration/doctype/data_migration_connector/connectors/ 目录下创建一个名为 atlas_connection.py 的新文件。其他连接器也存放在这里。

我们只需要为我们的 atlas 连接器实现 insert、update 和 delete 方法。我们还需要在 __init__ 方法中编写代码来连接到我们的 Atlas 实例。请参阅 frappe_connection.py 作为参考。

创建 Atlas 连接器后,我们还需要将其导入到 data_migration_connector.py 中

数据迁移运行

现在我们有了连接器,最后要做的事情是创建一个新的 数据迁移运行。

数据迁移运行接收一个数据迁移计划和一个数据迁移连接器,并根据我们的配置执行该计划。它负责处理排队、批处理、增量更新等。

只需点击“运行”。它将把我们的物料推送到远程 Atlas 实例,您可以看到实时更新的进度。

运行成功执行后,您不能再次运行它。您必须创建另一个运行并执行它。

数据迁移运行将尽可能高效,因此下次执行时,它将只推送上次运行中更改或失败的物料。

注意:数据迁移工具仍处于测试阶段。如果您发现任何问题,请在此处报告

重定向

您可以通过添加 website_redirects 钩子来添加重定向。

可选字段 redirect_http_status 允许您指定用于重定向的自定义 HTTP 状态码——如果未指定,默认使用 301。

示例

website_redirects = [
    # absolute location
    {"source": "/from", "target": "https://mysite/from"},

    # relative location
    {"source": "/from", "target": "/main", "redirect_http_status": 307},

    # use regex
    {"source": "/from/(.*)", "target": "/main/\1"}
]

生成器

如果表(DocType)中的每条记录都对应一个网页,您可以设置生成器。

要设置生成器,您必须:

  1. 添加一个字段 route 来指定页面的路由
  2. 添加一个条件字段,用于指示页面是否可见。
  3. 在您应用的 hooks.py 的 website_generators 中添加该 DocType 名称。
  4. 从 frappe.website.website_generator.WebsiteGenerator 继承控制器(Controller)
  5. 为您的页面创建一个模板
  6. 为模板添加自定义属性(上下文)
  7. 自定义路由和列表视图

让我们通过一个示例来说明:

示例

1. 添加字段

我们在 DocType 中添加了 published、route 字段

注意: 字段 route 是必填项

2. 将网站生成器添加到 Hooks

由于 Job Opening 位于 erpnext 中,我们已将其添加到现有的生成器 hooks 列表中:

website_generators = ["Item Group", "Item", "Sales Partner", "Job Opening"]

如果您的 hooks.py 中不存在 website_generators 属性,请添加它!

3. 控制器

我们在 job_opening.py 的 JobOpening 类中添加了 website 属性

在 get_context 中,parents 属性将用于指示面包屑导航

from frappe.website.website_generator import WebsiteGenerator
from frappe import _

# subclass from WebsiteGenerator, not Document
class JobOpening(WebsiteGenerator):
    website = frappe._dict(
        template = "templates/generators/job_opening.html",
        condition_field = "published",
        page_title_field = "job_title",
    )

    def get_context(self, context):
        # show breadcrumbs
        context.parents = [{'name': 'jobs', 'title': _('All Jobs') }]

注意: 完成此操作后,您应该会在文档表单上看到“在网站上查看”链接。

4. 添加模板

在 erpnext/templates/generators/job_opening.html 中添加模板

{% raw %}{% extends "templates/web.html" %}

{% block breadcrumbs %}
    {% include "templates/includes/breadcrumbs.html" %}
{% endblock %}

{% block header %}

<h1>{{ job_title }}</h1>
{% endblock %}

{% block page_content %}

<div>{{ description }}</div>

<a class="btn btn-primary" href="/job_application?job_title=%7B%7B%20doc.job_title%20%7D%7D">
    {{ _("Apply Now") }}</a>

{% endblock %}
{% endraw %}

5. 自定义列表视图

如果您在控制器文件(job_opening.py)中添加一个 get_list_view 方法,您可以为列表视图设置属性

def get_list_context(context):
    context.title = _("Jobs")
    context.introduction = _('Current Job Openings')

网页表单

Frappe 提供了一种简单的方法,只需很少的配置即可为您的网站生成表单。这些表单可以是公开的(任何人都可以填写),也可以配置为需要登录,还可以通过私密请求链接提供访问。

创建 Web 表单

要创建 Web 表单,请在 awesomebar 中输入“新建 Web 表单”并按回车键。

  1. 输入标题
  2. 选择要创建记录对应的 DocType(文档类型)。
  3. 添加一些介绍(可选)。
  4. 点击“获取字段”按钮,从所选 DocType 中获取所有字段,或者为您的 Web 表单手动选择字段。
  5. 发布表单,即可开始使用。

自定义 Web 表单 →

私密 Web 表单请求 →

标准 Web 表单

如果您勾选“标准”复选框,系统将在 Web 表单的
module 中创建一个新文件夹。在此文件夹中,您会看到一个 .py 和 .js 文件,
可用于配置 Web 表单。这些文件需要随您的自定义应用一起
纳入版本控制。您可以在任何站点上安装此应用,
该站点便会安装此 Web 表单。

Is Standard 字段仅在开发者模式下可见。

门户角色

版本:7.1+

可以为网站用户分配角色,他们将根据其角色看到相应的菜单

  1. 可以在门户设置中设置默认角色
  2. 每个门户菜单项都可以关联一个角色。如果设置了该角色,则只有拥有该角色的用户才能看到该菜单项
  3. 可以为默认角色设置规则,这些规则将在钩子(hooks)上应用于默认用户

默认角色规则

例如,如果电子邮件地址与联系人ID匹配,则设置角色为客户或供应商:

default_roles = [
{‘role’: ‘Customer’, ‘doctype’:’Contact’, ’email_field’: ’email_id’,
‘filters’: {‘ifnull(customer, “”)’: (‘!=’, ”)}},
{‘role’: ‘Supplier’, ‘doctype’:’Contact’, ’email_field’: ’email_id’,
‘filters’: {‘ifnull(supplier, “”)’: (‘!=’, ”)}},
{‘role’: ‘Student’, ‘doctype’:’Student’, ’email_field’: ‘student_email_id’}
]

动态页面

您可以使用 Jinja 模板语言动态渲染页面。要查询数据,您可以更新传递给模板的 context 对象。

这可以通过添加一个与模板同名的 .py 文件(例如,为 index.md 添加 index.py)并定义一个 get_context 方法来实现。

示例

如果您想显示一个查看用户的页面,请在 www/ 文件夹中创建一个 users.html 和一个 users.py 文件。

在 users.py 中:

import frappe
def get_context(context):
 context.users = frappe.get_list("User", fields=["first_name", "last_name"])

在 users.html 中:

### List of Users

{% for user in users %}
 2. {{ user.first_name }} {{ user.get("last_name", "") }}

{% endfor %}

目录

您可以通过在新行中添加 {index​} 字符串来添加目录。

您还可以通过在 {} 中添加 previous 或 next 来添加上一页和下一页按钮。

显示目录

这是一个标题

你好,段落

目录:

{index​} 将渲染为页面的编号列表,但仅在 index.md 或 index.html 中有效。

此页面的 {next​} 将渲染为:

{next}

添加页面

要添加页面,只需在 www 文件夹中添加 .html 或 .md 文件。页面内容中只能包含正文,不能包含 and 标签。

您也可以编写 Markdown 格式的页面。

索引

文件夹中的第一个文件必须命名为 index.md 或 index.html。

系统需要存在其中任一文件,才能将该文件夹视为有效的页面构建目录。

Markdown

这是一个标题

这是一些页面内容
一个链接

页面链接的 URL 可以省略 .html 扩展名,例如 /home/link。

标题

如果未在特殊标签中指定,第一个 “ 块(如果存在)将作为页面标题。如果既没有 `

` 也没有指定标题,则文件名将作为标题。

添加 CSS

您还可以添加一个与页面同名的 .css 文件(例如,为 index.md 添加 index.css),该文件将与页面一起渲染。

特殊标签

  1. “ 将使页面以 Jinja 模板方式渲染。
  2. “ 将添加自定义标题。
  3. “ 将不在页面中显示面包屑导航。
  4. “ 将启用缓存(如果您使用了 Jinja 模板)。
    ==========================================================================================================================================================================================================================================================================================================================================================================================================

下单

您可以通过在文件夹中定义 index.txt 文件来指定索引中页面的排序方式。index.txt 文件必须包含该文件夹中页面的名称(不带扩展名),以指示其顺序。

例如,对于此文件夹,index.txt 的内容如下所示:

添加页面
排序
内容
上下文
构建