Clojure RuntimeException - 标签db/id没有读取器功能

Geo*_*off 4 clojure clojurescript datomic edn

当我在Clojure中收到此错误时会发生什么?

java.lang.RuntimeException: No reader function for tag db/id
Run Code Online (Sandbox Code Playgroud)

Geo*_*off 7

标记文字

此错误消息与Clojure 1.7中引入的功能相关, 标记为文字.标记文字是一种简单的方法,用于扩展可以在Clojure代码或EDN 数据中表示为文字的数据类型.

Clojure的船舶与读者两个标记文字,#inst#uuid的允许文字表述java.util.Datejava.util.UUID.data_readers.clj文档中所述,可以通过在类路径中包含文件来添加对更多标记的支持 .

常见原因

导致此错误的一些常见原因:

  • 试图阅读包含#db/id文字的Datomic交易数据
  • 尝试使用EDN阅读器而不通过:readers
  • 在尝试通过传递使用EDN阅读器的Boot任务中 *data-readers*.

使用EDN阅读器

导致此错误的一个常见原因是尝试使用EDN阅读器 而不传递:readers选项.来自doc字符串 clojure.edn/read:

:readers  - a map of tag symbols to data-reader functions to be
            considered before default-data-readers. When not
            supplied, only the default-data-readers will be used.
Run Code Online (Sandbox Code Playgroud)

顾名思义,default-data-readers只是 Clojure本身附带的数据读取器的地图.也就是说,它不包括data_readers.clj您正在使用的任何库的文件中定义的任何读者(例如,Datomic).在这种情况下,解决方案是传递var中找到的当前加载数据读取器集 *data-readers*.

(clojure.edn/read {:readers *data-readers*} <your-read-source>)
Run Code Online (Sandbox Code Playgroud)

或者,更好的是,明确指定要使用的数据读取器的映射.例如,如果您希望只能使用数据源数据读取器:

(require 'datomic.db
         'datomic.function
         'datomic.codec)

(edn/read {:readers {'db/id  datomic.db/id-literal
                     'db/fn  datomic.function/construct
                     'base64 datomic.codec/base-64-literal}}
          <your-read-source-here>)
Run Code Online (Sandbox Code Playgroud)

当然,由于这些只是我们正在处理的clojure地图,我们还可以default-data-readers通过合并地图来包含:

(require 'datomic.db
         'datomic.function
         'datomic.codec)

(edn/read {:readers (merge
                     default-data-readers
                     {'db/id  datomic.db/id-literal
                      'db/fn  datomic.function/construct
                      'base64 datomic.codec/base-64-literal})}
          <your-read-source-here>)
Run Code Online (Sandbox Code Playgroud)