尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Asami事务与数据加载实战:transact、临时ID与批量导入的10个技巧

Asami事务与数据加载实战:transact、临时ID与批量导入的10个技巧 Asami事务与数据加载实战transact、临时ID与批量导入的10个技巧【免费下载链接】asamiA graph store for Clojure and ClojureScript项目地址: https://gitcode.com/gh_mirrors/asa/asamiAsami 是一款为 Clojure 和 ClojureScript 打造的图数据库以免模式schema-less和无需配置即可运行著称。对新手来说最常接触也最容易踩坑的地方正是事务transact与数据加载如何提交数据、如何用临时 ID 关联实体、如何高效批量导入。本文整理了 10 个实战技巧帮你快速上手 Asami 的数据写入流程少走弯路。所有示例基于asami.core的公开 API源码位于 core.cljc。技巧一认识 transact——Asami 写入数据的唯一入口在 Asami 中所有数据写入都通过transact完成。它接受一个连接connection和事务数据事务数据可以是实体 map 列表也可以是声明语句datom向量。最简单的一次事务如下(require [asami.core :as d]) (def db-uri asami:mem://movies) (d/create-database db-uri) (def conn (d/connect db-uri)) (d/transact conn {:tx-data [{:movie/title Explorers :movie/genre adventure}]})其中create-database与connect负责创建并建立连接asami:mem://表示纯内存存储若改为asami:local://数据则会持久化到本地磁盘目录。核心实现见 core.cljc。技巧二别忘了 deref——事务是异步的 ⏳在 JVM 上transact是异步执行的返回的是一个 future。立即调用(d/db conn)可能拿不到最新数据。正确做法是deref等待事务完成返回值包含四个关键字段:db-before事务前的数据库值:db-after事务后的数据库值:tx-data本次产生的 datom 序列:tempids临时 ID 到真实节点 ID 的映射如果事务超过默认 100 秒仍未完成transact会抛出超时异常可通过系统属性asami.txTimeoutMsec调整。技巧三用临时 ID 关联实体——负数就是占位符 ️在一条事务里如果多个实体要互相引用比如Fred 的配偶是 Wilma可以用负数 ID作为临时 ID。Asami 会把负数解释为本事务内新建的节点占位符并在提交时统一分配真实 ID。临时 ID 的判断逻辑见 entities.cljc。(d/transact conn [{:db/id -1 :name Fred} {:db/id -2 :name Wilma} [:db/add -1 :spouse -2] [:db/add -2 :spouse -1}])这样 Fred 与 Wilma 就通过配偶关系关联起来了无需预先知道任何真实 ID。技巧四用 :db/ident 给实体命名——告别裸 ID跨事务引用节点时硬记内部 ID 很痛苦。给实体加上:db/ident字段即可起名之后任何事务都可以用它定位实体(d/transact conn [{:db/ident sense :movie/title Sense and Sensibility :movie/release-year 1996}])注意:db/ident本身不会出现在实体中但会作为属性存储在图上可被查询。技巧五从 tempids 中取回新节点 ID 事务提交后如何拿到新实体的真实 ID答案在返回值的:tempids映射里临时 ID负数或:db/ident值会映射到系统分配的真实节点 ID。(def result (d/transact conn [{:db/ident sense :movie/title ...}])) ;; 用 :db/ident 当 key 取回节点 (def sense (get (:tempids result) sense)) (d/entity (d/db conn) sense)这样你就能立刻用新节点做后续操作无需再写一次查询。技巧六用带 的属性做更新——覆盖旧值 Asami 遵循开放世界假设同一属性可以有多值。若想覆盖已有属性只需在属性名末尾加单引号。例如修正《理智与情感》的年份(d/transact conn [{:db/ident sense :movie/release-year 1995}])带的属性会先删除旧值再写入新值不带则追加多值。注意更新操作必须用:db/id或:db/ident定位到已存在节点否则会报错相关逻辑见 entities.cljc。技巧七用 [:db/add] 与 [:db/retract] 精细控制当你只想添加或删除某一条关系时使用声明语句向量比 map 更精确;; 添加关系 [:db/add -1 :pet -4] ;; 删除关系 [:db/retract [:db/ident bobid] :person/age 42]语句中的实体既可以是临时 ID也可以是 lookup ref见技巧八。多个语句可以混在一条事务里一次提交原子生效。技巧八lookup ref 引用——用属性值当外键除了临时 IDAsami 还支持用[:db/ident 值]这种查找引用lookup ref来指代实体。它在事务中被自动解析为真实节点非常适合在导入数据时引用已存在的实体[:db/add [:db/ident bobid] :person/friend [:db/ident aliceid]]实现位于resolve-lookup-refsentities.cljc解析不到时会保持原值并直接当作字面量使用。技巧九批量导入用 :tx-triples——绕过 map 转换开销 当数据量很大比如从 CSV 或 JSON 转换而来逐条转成实体 map 很慢。此时可以直接用:tx-triples提交原始三元组[实体 属性 值]跳过实体解析性能最好(d/transact conn {:tx-triples [[:mem/node-1 :property value] [:mem/node-2 :property value2]]})若担心单次事务过大还可通过:input-limit设置插入语句的数量上限超出会抛出带:overflow标记的异常参考 core.cljc。技巧十import-data / export-data 快速迁移与备份 Asami 提供了配套的导入导出函数core.cljc可快速完成数据备份、迁移和批量加载;; 导出为 EDN 字符串 (def dump (d/export-str db)) ;; 从 EDN 字符串/序列导入支持 JSON 文件内容 (d/import-data conn dump)import-data直接走:tx-triples通道不做重复性检查适合一次性灌入大量数据而export-data会把图中所有语句解析出来。此外Asami 还自带命令行工具可直接加载 JSON/EDN 文件入库asami asami:mem://tmp -f data.json升级 2.1.0 之前的旧库时官方也推荐用export-dataimport-data完成数据搬运这是最稳妥的迁移方式。写在最后从一条transact开始到临时 ID 关联、:db/ident命名、属性更新再到:tx-triples与import-data的批量加载这 10 个技巧基本覆盖了 Asami 事务与数据加载的核心场景。想深入源码的话可以 clone 仓库本地研读git clone https://link.gitcode.com/i/02a386b5f19ec9639ac35bd8c423f827重点看 entities.cljc 与 core.cljc 两个文件。掌握这些你就能自信地把数据喂给 Asami并正确、高效地维护你的图了。【免费下载链接】asamiA graph store for Clojure and ClojureScript项目地址: https://gitcode.com/gh_mirrors/asa/asami创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表