TypeScript v2 的本体编辑
v2 函数不只读取,还能构造一批本体编辑:改属性、改链接、创建对象、删除对象,甚至编辑结构体属性。
https://www.palantir.com/docs/foundry/functions/typescript-v2-ontology-edits/
原始标题:TypeScript v2 > Ontology edits
先记住这几条
写在前面
除了编写从 Ontology 读取数据的函数之外,你还可以编写用于创建对象、编辑对象属性与对象间链接的函数。本页介绍函数中可用的对象编辑 API。关于编辑函数如何工作的更多细节,请参阅概览页。
要使函数中创建的编辑真正被应用,Ontology 编辑函数必须被配置为一个函数支撑的动作(function-backed Action)。以这种方式配置动作,让你可以提供额外的元数据、配置权限,并在各种运营界面中访问该动作。正如文档所述,在动作之外运行编辑函数并不会真正修改任何对象数据。
标准的 Ontology 编辑使用一个编辑批次(edit batch)。TypeScript v2 还支持暂存写入(staged writes),它在函数内提供「写后可读」保障:编辑对同一次执行中后续的查询立即可见,且嵌套的暂存写入函数调用共享这些编辑。当函数必须读取它刚刚写入的数据时,请使用暂存写入。暂存写入目前处于测试(beta)开发阶段,在你的租户中可能不可用。
:::callout{theme="warning" title="意外的搜索结果影响的是编辑批次,而非暂存写入"}
当你使用编辑批次时,在编辑对象后立即搜索它们可能返回意外结果。这一注意事项不适用于暂存写入。详见 Caveats 一节。
定义编辑函数
定义编辑函数
编辑 Ontology 的函数必须显式声明将要被编辑的实体,使用从 @osdk/functions 包导出的 Edits 类型。下面的例子声明了一个新类型,表示对 Employee 与 Ticket 对象类型以及 Employee 与 Ticket 之间链接类型的编辑。多个实体的编辑需要用 | 运算符连接。
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[] {
// ...
}构造编辑批次
构造编辑批次
要在 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);
// ...
}该批次用于跟踪函数中所做的所有编辑。
更新属性
更新属性
Object properties
使用所创建批次上的 update 方法修改一个或多个对象属性:
batch.update(employee, { lastName: newName });如果你尚未将 employee 对象实例加载到内存,也可以通过引用对象的 API 名称与主键来更新它:
batch.update({ $apiName: "Employee", $primaryKey: 23 }, { lastName: newName });在同一函数执行的后半段,再次访问 employee 的 lastName 属性值,将不会反映你在编辑批次上调用 update 时所做的更改。
有时,将一个对象类型某个实例的所有属性值复制到另一个实例是很有用的。下面的例子将 employee2 的属性值赋给 employee1:
batch.update(employee1, employee2);已有对象的主键属性值无法被更新。
Interface properties
你可以使用 update 方法通过一个 Ontology 接口修改对象的接口属性。在下面的例子中,person 的类型是一个 Ontology 接口,但其底层实例是一个实现 Person 接口的对象。
update 方法对于对象类型和接口都接受两个参数。对于接口,它接受将被修改的接口以及将被修改的接口属性。
batch.update(person, { firstName: newFirstName });由底层对象的主键属性实现的接口属性无法被更新。
更新链接
更新链接
对于多对多链接,所创建批次上提供了 link 与 unlink 方法,用于在对象之间添加或移除链接。
// 将一名员工分配到一个办公室。
batch.link(employee, "office", office);
// 解除员工与办公室的分配。
batch.unlink(employee, "office", office);对于一对一与一对多链接,使用所创建批次上的 update 方法修改源对象的外键属性。下面的例子展示了一对多链接。一名员工可以有多个工单,但每个工单只能有一名员工。
// 将工单分配给员工。
batch.update({ $apiName: "Ticket", $primaryKey: 13 }, { assignedEmployeeId: 52 });
// 解除工单的分配。
batch.update({ $apiName: "Ticket", $primaryKey: 13 }, { assignedEmployeeId: undefined });与更新属性类似,如果你之前没有加载过对象类型的具体实例,也可以用 API 名称与主键引用链接的任意一侧。
// 将工单分配给员工。
batch.link({ $apiName: "Employee", $primaryKey: 23 }, "assignedTickets", { $apiName: "Ticket", $primaryKey: 12 });
// 解除员工与工单的分配。
batch.unlink({ $apiName: "Employee", $primaryKey: 23 }, "assignedTickets", { $apiName: "Ticket", $primaryKey: 12 });创建对象
创建对象
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",
});删除对象
删除对象
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);结构体属性上的编辑
结构体属性上的编辑
对象类型与接口类型的 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 的本体编辑」,读者最常问的几个问题。