具有Persistent Haskell的现有数据库中的外键

时间:2016-05-12 09:10:06

标签: sql haskell persistent

我目前正在使用Haskell和Persistent进行一个项目,我在一个小问题上运行。我想编写一个小型库来处理一种通用的身份验证方法,每个用户获得一个“身份”。

此标识使用persistent。

存储在数据库中
Identity
  lastSeen       UTCTime
  registration   UTCTime
  karma          Int DEFAULT=0
  banned         UTCTime Maybe

我的想法是我的lib的用户可以将他们的帐户数据类型添加到身份。我的问题是,当我将类型IdentityId提供给我的用户数据类型的字段时,该列是一个整数(没关系),但缺少引用约束。

例如:

User
  email          Text
  identity       IdentityId
  UniqueIdentity identity

我明白了:

Migrating: CREATE TABLE "identity"("id" INTEGER PRIMARY KEY,"last_seen" TIMESTAMP NOT NULL,"registration" TIMESTAMP NOT NULL,"karma" INTEGER NOT NULL,"banned" TIMESTAMP NULL)
Migrating: CREATE TABLE "user"("id" INTEGER PRIMARY KEY,"email" VARCHAR NOT NULL,"identity" INTEGER NOT NULL,CONSTRAINT "unique_identity" UNIQUE ("identity"))

诀窍是:用户的定义是在不同的文件中完成的,我想问题就在这里。

我可以做些什么来强制持久性添加引用约束吗?

提前谢谢你!

1 个答案:

答案 0 :(得分:1)

我假设您使用的是SQLite。 SQLite支持外键约束,但默认情况下,它们不会打开。您必须在迁移之前将其打开。

SQLite Foreign Key Support: 2. Enabling Foreign Key Support

这是打开它们的SQLite命令:

PRAGMA foreign_keys = ON;

您可以使用以下代码通过Haskell和Persistent打开此PRAGMA:

import qualified Database.Sqlite as Sqlite
import Database.Persist.Sqlite (createSqlPool, wrapConnection)

enableForeignKeys :: Sqlite.Connection -> IO ()
enableForeignKeys conn = Sqlite.prepare conn "PRAGMA foreign_keys = ON;" >>= void . Sqlite.step

createSqliteBackend :: Text -> LogFunc -> IO SqlBackend
createSqliteBackend connStr logFunc = do
  conn <- Sqlite.open connStr
  enableForeignKeys conn
  wrapConnection conn logFunc

createSqliteBackend将返回SqlBackend,该foreign_keys会在RestTemplate Pragma打开的情况下运行持久性查询。

Yesod Cookbook: Activate foreign key checking in Sqlite