datomic:transact函数并没有真正写入数据库

use*_*709 3 clojure datomic

我在datomic-free中运行dev db

但是,我认为它会向数据库写一些东西但是当我做拉动时,它就不存在了.这是我的peer.clj

(ns dank.peer
  (:require [datomic.api :as d :refer (q)]
            [clojure.pprint :as pp]))

; Name the database as a uri
(def uri "datomic:mem://dank")

; Read the schema and seed data as strings
(def schema-tx (read-string (slurp "resources/dank/schema.edn")))
(def data-tx (read-string (slurp "resources/dank/seed-data.edn")))

; Initialize the db with above vars
(defn init-db
  []
  (when (d/create-database uri)
    (let
      [conn (d/connect uri)]
      @(d/transact conn schema-tx)
      @(d/transact conn data-tx))))

(init-db)

(def conn (d/connect uri))
(def db (d/db conn))

(defn create
  "Creates a new note"
  [notes]
    @(d/transact
      conn
      [{:db/id #db/id[:db.part/user]
        :item/author "default"
        :item/notes notes}]))

(defn get-notes
  [author]
    (d/pull-many db '[*]
      (flatten (into []
       (q '[:find ?e
            :in $ ?author
           :where
           [?e :item/author ?author]]
          db
          author
         )))))
Run Code Online (Sandbox Code Playgroud)

(create "some note") ---->显示前后的整个事务数据结构.

(get-notes "default") ---> []它是空的!

我在这里错过了什么吗?

Mar*_*all 6

mavbozo的回答是正确的,当你调用你的get-notes函数时,你在处理新笔记之前使用的是数据库的值.

如果您(def db (d/db conn))之前再次打电话,get-notes您将在数据库中看到新数据.

但是,通常最好避免将连接或数据库作为全局变量处理,因为它可以防止功能行为严格地从其参数中确定.正如您所注意到的,行为get-notes取决于db全局状态中变量的状态.根据经验,最好将数据库值传递给查询或从数据库中提取的函数,并将连接传递给对数据库进行事务处理的函数或监视数据库状态(参见http:// docs. datomic.com/best-practices.html#consistent-db-value-for-unit-of-work,有关Datomic数据库的各个值的更多讨论).

在这种情况下,您的get-notes功能可能是这样的:

(defn get-notes
  [db author]
    (d/q '[:find (pull ?e [*])  
           :in $ ?author
           :where
           [?e :item/author ?author]]
          db
          author))
Run Code Online (Sandbox Code Playgroud)

然后您可以通过以下方式调用:

(get-notes (d/db conn) "default")
Run Code Online (Sandbox Code Playgroud)

查询最新版本的数据库.此方法还具有以下优点:您可以get-notes使用任何数据库值(即最近的,过去给定时间的一个或历史数据库)进行调用.

同样,我建议更改您的create函数以获取连接,而不是使用全局定义的conn.

至于管理连接,最好尽可能避免使用全局变量.一些首选选项可能是将连接放入应用程序状态映射或在整个程序中传递的原子(如果适用).另一个经常使用的好选择是利用Stuart Sierra的组件库(https://github.com/stuartsierra/component)来管理连接的生命周期.