循序渐进 · 教学 · TypeScript v2(四)

TypeScript v2 的本体编辑

v2 函数不只读取,还能构造一批本体编辑:改属性、改链接、创建对象、删除对象,甚至编辑结构体属性。

全部目录 ← 上一篇 TypeScript v2 的本体编辑 下一篇 →
本文来源 · Source 内容整理自 Palantir Foundry 官方文档:
https://www.palantir.com/docs/foundry/functions/typescript-v2-ontology-edits/
原始标题:TypeScript v2 > Ontology edits

先记住这几条

① 编辑要打包成 batch
多个编辑操作组装成一个批次返回。
② 增删改全覆盖
更新属性、更新链接、创建对象、删除对象四类。
③ 接口也能作为编辑目标
除了对象,接口上的属性和对象同样可编辑。
④ 结构体属性单独处理
struct 属性的编辑有专门写法。
0

写在前面

除了编写从 Ontology 读取数据的函数之外,你还可以编写用于创建对象、编辑对象属性与对象间链接的函数。本页介绍函数中可用的对象编辑 API。关于编辑函数如何工作的更多细节,请参阅概览页

要使函数中创建的编辑真正被应用,Ontology 编辑函数必须被配置为一个函数支撑的动作(function-backed Action)。以这种方式配置动作,让你可以提供额外的元数据、配置权限,并在各种运营界面中访问该动作。正如文档所述,在动作之外运行编辑函数并不会真正修改任何对象数据。

标准的 Ontology 编辑使用一个编辑批次(edit batch)。TypeScript v2 还支持暂存写入(staged writes),它在函数内提供「写后可读」保障:编辑对同一次执行中后续的查询立即可见,且嵌套的暂存写入函数调用共享这些编辑。当函数必须读取它刚刚写入的数据时,请使用暂存写入。暂存写入目前处于测试(beta)开发阶段,在你的租户中可能不可用。

:::callout{theme="warning" title="意外的搜索结果影响的是编辑批次,而非暂存写入"}

当你使用编辑批次时,在编辑对象后立即搜索它们可能返回意外结果。这一注意事项不适用于暂存写入。详见 Caveats 一节

1

定义编辑函数

定义编辑函数

要点:什么样的函数才能返回编辑。

编辑 Ontology 的函数必须显式声明将要被编辑的实体,使用从 @osdk/functions 包导出的 Edits 类型。下面的例子声明了一个新类型,表示对 EmployeeTicket 对象类型以及 EmployeeTicket 之间链接类型的编辑。多个实体的编辑需要用 | 运算符连接。

import { Employee, Person, Ticket } from "@ontology/sdk";
import { Edits } from "@osdk/functions";

type OntologyEdit = Edits.Object<Employee> | Edits.Interface<Person> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;

然后你必须声明该函数返回新类型的编辑数组。

export default function createNewTicketAndAssignToEmployee(): OntologyEdit[] {
    // ...
}
2

构造编辑批次

构造编辑批次

要点:把多个编辑组装成一个 batch。

要在 TypeScript v2 函数中执行 Ontology 编辑,首先使用从 @osdk/functions 导出的 createEditBatch 函数构造一个 Ontology 编辑批次,将之前声明的类型作为类型参数传入:

import { Employee, Ticket } from "@ontology/sdk";
import { Client } from "@osdk/client";
import { createEditBatch, Edits } from "@osdk/functions";

type OntologyEdit = Edits.Object<Employee> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;

export default function createNewTicketAndAssignToEmployee(client: Client): OntologyEdit[] {

    const batch = createEditBatch<OntologyEdit>(client);
    // ...
}

该批次用于跟踪函数中所做的所有编辑。

3

更新属性

更新属性

要点:对象属性与接口属性的更新写法。

Object properties

使用所创建批次上的 update 方法修改一个或多个对象属性:

batch.update(employee, { lastName: newName });

如果你尚未将 employee 对象实例加载到内存,也可以通过引用对象的 API 名称与主键来更新它:

batch.update({ $apiName: "Employee", $primaryKey: 23 }, { lastName: newName });

在同一函数执行的后半段,再次访问 employeelastName 属性值,将不会反映你在编辑批次上调用 update 时所做的更改。

有时,将一个对象类型某个实例的所有属性值复制到另一个实例是很有用的。下面的例子将 employee2 的属性值赋给 employee1

batch.update(employee1, employee2);

已有对象的主键属性值无法被更新。

Interface properties

你可以使用 update 方法通过一个 Ontology 接口修改对象的接口属性。在下面的例子中,person 的类型是一个 Ontology 接口,但其底层实例是一个实现 Person 接口的对象。

update 方法对于对象类型和接口都接受两个参数。对于接口,它接受将被修改的接口以及将被修改的接口属性。

batch.update(person, { firstName: newFirstName });

由底层对象的主键属性实现的接口属性无法被更新。

5

创建对象

创建对象

要点:创建对象与接口实例。

Objects

你可以使用编辑批次上的 create 方法创建新对象。创建新对象时,必须为它的主键指定一个值,并可以可选地初始化任何其他属性。

在这个例子中,我们用给定的 ID 创建一个新 Ticket 对象,设置其 dueDate 属性,并通过修改 assignedTickets 链接将它分配给给定的 Employee。为了简化 dueDate 新值的计算,我们使用了 luxon 库。

import { Employee, Ticket } from "@ontology/sdk";
import { Client, Osdk } from "@osdk/client";
import { createEditBatch, Edits, Integer } from "@osdk/functions";
import { DateTime } from "luxon";

type OntologyEdit = Edits.Object<Employee> | Edits.Object<Ticket> | Edits.Link<Employee, "assignedTickets">;

export default function createNewTicketAndAssignToEmployee(
    client: Client,
    employee: Osdk.Instance<Employee>,
    ticketId: Integer,
): OntologyEdit[] {
    const batch = createEditBatch<OntologyEdit>(client);

    batch.create(Ticket, {
        ticketId,
        dueDate: DateTime.now().plus({ days: 7 }).toFormat('yyyy-MM-dd'),
    });

    // 新工单在 Ontology 中还不是一个具体实例,但我们可以通过引用它的 API 名称和主键来链接它
    batch.link(employee, "assignedTickets", { $apiName: "Ticket", $primaryKey: ticketId });

    return batch.getEdits();
}

Interfaces

你可以通过调用 create 方法并指定一个接口、底层对象类型以及一组接口属性,来通过接口创建新的对象实例。所提供的接口属性中,必须有一个由底层对象类型的主键属性实现。

editBatch.create(Person, {
    $objectType: "Employee",
    firstName: "John",
    lastName: "Doe",
});
6

删除对象

删除对象

要点:删除对象与接口实例。

Objects

你可以通过调用编辑批次上的 delete 方法删除一个对象。

在这个例子中,我们删除分配给给定员工的所有工单:

for await (const ticket of employee.$link.assignedTickets.asyncIter()) {
    batch.delete(ticket);
}

也可以使用主键而非实例来删除对象:

batch.delete({ $apiName: "Ticket", $primaryKey: 12 });

Interfaces

你可以通过调用 delete 方法通过一个接口删除一个对象。

batch.delete(person);
7

结构体属性上的编辑

结构体属性上的编辑

要点:struct 类型属性的特殊处理。

对象类型与接口类型的 Ontology struct(结构体)属性都可以用 TypeScript v2 函数编辑。TypeScript v2 中的 Struct 类型 使用 TypeScript 接口定义。函数中的 Struct 类型可用于编辑 Ontology struct 属性,只要它们包含与 struct 属性相同的字段,且字段名与 Ontology struct 属性字段的 API 名称匹配。

interface Address {
    street: string,
    city: string,
    state: string,
    country: string,
    zipcode: string,
}

export default function updateEmployeeAddress(
    client: Client,
    employee: Osdk.Instance<Employee>,
    newAddress: Address
): OntologyEdit[] {
    const batch = createEditBatch<OntologyEdit>(client);
    batch.update(employee, { address: newAddress });
    return batch.getEdits();
}

延伸阅读 · 相关页面

按主题横向跳转,不必顺着目录一篇篇读。

常见问题速答 · FAQ

关于「TypeScript v2 的本体编辑」,读者最常问的几个问题。

定义编辑函数是什么?
什么样的函数才能返回编辑。编辑 Ontology 的函数必须显式声明将要被编辑的实体,使用从 @osdk/functions 包导出的 Edits 类型。
构造编辑批次是什么?
把多个编辑组装成一个 batch。要在 TypeScript v2 函数中执行 Ontology 编辑,首先使用从 @osdk/functions 导出的 createEditBatch 函数构造一个 Ontology 编辑批次,将之前声明的类型作为类型参数传…
更新属性是什么?
对象属性与接口属性的更新写法。使用所创建批次上的 update 方法修改一个或多个对象属性。
更新链接是什么?
修改对象之间的链接关系。对于多对多链接,所创建批次上提供了 link 与 unlink 方法,用于在对象之间添加或移除链接。