Dataloader安装使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dataloader安装使用相关的知识,希望对你有一定的参考价值。
参考技术A Dataloader是salesforce的数据批量导入导出工具。可以用工具执行导入导出操作,也可以使用命令行(仅windows可用)的方式实现定时导入导出功能。一、安装
安装分两步:安装zulu jdk和dataloader客户端
首先使用 .MSI 文件(不能用zip)安装Zulu OpenJDK 版本 11
路径: https://www.azul.com/downloads/zulu-community/?architecture=x86-64-bit&package=jdk
然后安装dataloader,我用的版本v48,zulu jdk11 required. 安装后默认的路径是c:\user
(不知道为啥快捷方式没安装成功,所以去user目录找到的)
二、设置
使用前可根据需要修改默认设置,有几个设置简单说明:
1.Batch Size-单次导入导出的数据量,
2.Use Bulk API - 上图可以看到安装后Hard Delete默认是disable,在settings中勾选Use Bulk API后启用. 要注意的是Hard Delete是立即删除,数据不会到回收站,所以要谨慎使用该功能。
3.Time Zone - 这个主要涉及到日期字段的导入导出。
三、导入导出
Insert-- 即import,导入时选择csv格式的模板(可先利用export功能导出一个模板完善数据后使用),别忘了设置Mapping关系。
Update--相当于编辑记录,只更新存在的记录。
Upsert -- 是Insert和Update的结合,如果记录存在则更新,不存在则创建。(是不是当需要导入数据或更新数据时都可以用Upsert)
Delete -- 从salesforce中删除记录到回收站,回收站也会有数据限制。Hard delete是彻底删除,不会保存到回收站
Export -- 导出数据,目前Dataloader不支持导出附件。
Export All -- 没看出跟Export有啥区别?
以导出数据为例:登录后,选择要导出的对象、字段和筛选条件,导出即可。
在Insert \ Update \ Upsert 和Delete中,都需要设置字段映射,可使用Auto-Match Fields to Columns快速映射。
四、使用命令行 -- 待熟练后再使用并更新
使用 Dataloader 处理 GraphQL 字段参数?
【中文标题】使用 Dataloader 处理 GraphQL 字段参数?【英文标题】:handling GraphQL field arguments using Dataloader? 【发布时间】:2019-10-09 12:22:52 【问题描述】:我想知道在使用 Dataloader 时如何最好地处理 GraphQL 字段参数方面是否存在任何共识。 Dataloader 需要的batchFn
批处理函数期望接收Array<key>
并返回Array<Promise>
,通常只需调用load( parent.id )
,其中parent
是给定字段的解析器的第一个参数。在大多数情况下,这很好,但如果您需要为嵌套字段提供参数怎么办?
例如,假设我有一个 SQL 数据库,其中包含 Users
、Books
的表和一个名为 BooksRead
的关系表,它们表示 Users:Books 之间的 1:many 关系。
我可能会运行以下查询,以查看所有用户阅读的书籍:
query
users
id
first_name
books_read
title
author
name
year_published
假设context
中有一个BooksReadLoader
,这样books_read
的解析器可能如下所示:
const UserResolvers =
books_read: async function getBooksRead( user, args, context )
return await context.loaders.booksRead.load( user.id );
;
BooksReadLoader
的批量加载函数将对数据访问层方法进行async
调用,该方法将运行一些 SQL,例如:
SELECT B.* FROM Books B INNER JOIN BooksRead BR ON B.id = BR.book_id WHERE BR.user_id IN(?);
我们将从结果行创建一些 Book
实例,按 user_id
分组,然后返回 keys.map(fn)
以确保我们将正确的书籍分配给加载器缓存中的每个 user_id
键。
现在假设我向books_read
添加一个参数,询问用户阅读过的所有在 1950 年之前出版的书籍:
query
users
id
first_name
books_read(published_before: 1950)
title
author
name
year_published
理论上,我们可以运行相同的 SQL 语句,并在解析器中处理参数:
const UserResolvers =
books_read: async function getBooksRead( user, args, context )
const books_read = await context.loaders.booksRead.load( user.id );
return books_read.filter( function ( book )
return book.year_published < args.published_before;
);
;
但是,这并不理想,因为我们仍在从Books
表中获取潜在的大量行,而实际上可能只有少数行满足该参数。改为执行此 SQL 语句要好得多:
SELECT B.* FROM Books B INNER JOIN BooksRead BR ON B.id = BR.book_id WHERE BR.user_id IN(?) AND B.year_published < ?;
我的问题是,通过new DataLoader( batchFn[, options] )
提供的cacheKeyFn
选项是否允许向下传递字段的参数以在数据访问层中构造动态SQL 语句?我已经查看了https://github.com/graphql/dataloader/issues/75,但我仍然不清楚cacheKeyFn
是否适合。我正在使用apollo-server-express
。还有这个其他 SO 问题:Passing down arguments using Facebook's DataLoader 但它没有答案,我很难找到其他来源。
谢谢!
【问题讨论】:
顺便说一句,在这种情况下您真的需要数据加载器吗?除非客户端实际上在同一请求中为 same 用户多次请求books_read
,否则为该字段实现数据加载器没有任何好处。
嗨@DanielRearden 你是什么意思?在我的查询示例中,我假设响应将是一个数组 ([User]
),而不是单个 User
。抱歉,如果我在我的问题中不清楚这一点。由于查询是针对许多用户的,我假设我希望数据加载器收集所有 user_id
s,以便我可以将它们发送到像 SELECT id, first_name FROM User WHERE id IN(?);
这样的 SQL 语句,因为 books_read
是每个用户的字段,而 @987654359解析器的@ 是单个User
,我是否也希望数据加载器批量处理那些user_id
s?
我们continue this conversation in chat
【参考方案1】:
将 id 和 params 作为单个对象传递给 load 函数,如下所示:
const UserResolvers =
books_read: async function getBooksRead( user, args, context )
return context.loaders.booksRead.load(id: user.id, ...args);
;
然后让批量加载函数找出如何以最佳方式满足它。
您还需要为对象的构造做一些记忆,否则数据加载器的缓存将无法正常工作(我认为它基于身份而不是深度相等工作)。
【讨论】:
您还可以将自定义的 cacheKeyFn 或 cacheMap 传递给 Dataloader,它执行类似 JSON 字符串化缓存键的操作,那么您就不需要记忆了。 虽然这是一个很好的 hack,但这会破坏打字,与打字稿不兼容以上是关于Dataloader安装使用的主要内容,如果未能解决你的问题,请参考以下文章