使用 clsql 在 postgresql 中自动生成主键
Posted
技术标签:
【中文标题】使用 clsql 在 postgresql 中自动生成主键【英文标题】:Autogenerated primary key in postgresql with clsql 【发布时间】:2016-04-18 07:23:41 【问题描述】:我正在尝试使用 Common Lisp ORM 创建一个简单的数据库。我使用 PostgreSQL 和 CLSQL。我可以创建类并生成表,但是当我想插入一个没有主键的值以获得生成的值时,它不起作用。似乎它适用于mysql数据库。用 PostgreSQL 可以做到这一点吗?
我将主键定义为:
(id :db-kind :key
:db-type "serial"
:db-constraints (:not-null :unique)
:type integer
:initarg :id)
我得到这个错误:
While accessing database #<POSTGRESQL-DATABASE localhost/cl_ormex/postgres OPEN 1004FCC403>
with expression "SELECT currval ('NIL')":
Error 42P01 / relation "nil" does not exist
LINE 1: SELECT currval ('NIL')
^
has occurred.
[Condition of type SQL-DATABASE-DATA-ERROR]
我将 PostgreSQL 9.5.2 与 SBCL 1.3.1 一起使用。
编辑
这是一个例子:
(require 'clsql)
(defpackage :orm-ex (:use :cl :clsql))
(in-package :orm-ex)
(file-enable-sql-reader-syntax)
(enable-sql-reader-syntax)
(setf *default-caching* nil)
(connect '("localhost" "examp" "postgres" "postgres")
:database-type :postgresql)
(def-view-class person ()
((id :db-kind :key
:db-type "serial"
:db-constraints (:not-null :unique)
:type integer
:initarg :id
:accessor person-id)
(name :type (varchar 30)
:initarg :name
:accessor person-name)))
(defparameter person1
(make-instance 'person
:name "Matt"))
(dolist (c '(person)) (create-view-from-class c))
(update-records-from-instance person1)
我不是很明白这个错误,但是该行似乎插入到数据库中。
【问题讨论】:
一个完整的、最小的例子会很有帮助,还有堆栈跟踪。 好的。我添加了一个示例... 实际上,我注意到,所有字段都已插入(还有 id),但对象中的 id 插槽仍未定义... 【参考方案1】:来自 Mark Watson 的 Loving Lisp - db-constraints
需要用 :auto-increment
定义。注意 - 截至今天(25/10/2019)的图书版本不正确,但下载的代码是:
(clsql:def-view-class article ()
((id
:db-kind :key
:db-constraints (:auto-increment :not-null :unique)
:type integer
:initarg :id)
(uri
:accessor uri
:type (string 60)
:initarg :uri)
(title
:accessor title
:type (string 90)
:initarg :title)
(text
:accessor text
:type (string 500)
:nulls-ok t
:initarg :text)))
【讨论】:
我还应该指出,如果您在没有上述约束的情况下创建了表属性,则需要更新它。就我而言,其中没有数据,因此我将其删除并使用新的类详细信息从 lisp 重新创建它。【参考方案2】:这似乎行不通。它有一个todo file,上面写着:
测试“:db-kind :key”是否为该键添加了索引。这因显示自动生成的主键的不同后端而变得复杂 以不同的方式。
所以也许它不适用于 Postgres。我相信你有很多可能。
使用其他更新一些的框架,例如 cl-dbi,take a look here:
cl-dbi 为各种数据库服务器特定的库(cl-postgres、cl-mysql 等)提供统一的接口。 SxQL 为构建安全、自动参数化的 SQL 查询提供了 DSL。
有两个相当完整的 ORM:Crane,由你真正的,和 Integral,由 cl-dbi 的作者。 合并: 不鼓励使用 cl-dbi 以外的任何东西。 未来的工作: 其他数据库系统的绑定,例如甲骨文,存在。为 cl-dbi 编写驱动程序将是最好的做法并有助于整合。
我发现生成 ID 很容易,可以使用时间戳轻松按创建时间升序或降序排序,或者您也可以使用生成器或考虑您插入的最后一个数字
但这会起作用,通用时间并添加一个随机数,用于同时创建许多实体并具有低碰撞率
(format nil "~12,'0d-~6,'0d" (get-universal-time) (random 1000000))
【讨论】:
以上是关于使用 clsql 在 postgresql 中自动生成主键的主要内容,如果未能解决你的问题,请参考以下文章
在迁移中更改自动增量值(PostgreSQL 和 SQLite3)
如何使用 PostgreSQL 在 DBeaver 中创建自动递增/SERIAL id 列?