Внешний ключ из существующей базы данных с Persistent Haskell

В настоящее время я работаю над проектом с использованием Haskell и Persistent, и у меня возникла небольшая проблема. Я хочу закодировать небольшую библиотеку, чтобы иметь дело с общим подходом к аутентификации, когда каждый пользователь получает «идентификацию».

Эта идентификация хранится в базе данных с использованием постоянного.

Identity
  lastSeen       UTCTime
  registration   UTCTime
  karma          Int DEFAULT=0
  banned         UTCTime Maybe

Моя идея состоит в том, что пользователи моей библиотеки могут добавить сопоставление типа данных своей учетной записи с личностью. Моя проблема в том, что когда я даю тип 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"))

Хитрость в том, что определение пользователя выполняется в другом файле, и я полагаю, что проблема здесь.

Могу ли я что-то сделать, чтобы заставить постоянный добавить ограничение ссылок?

Заранее спасибо!


person lthms    schedule 12.05.2016    source источник


Ответы (1)


Я предполагаю, что вы используете SQLite. SQLite поддерживает ограничения внешнего ключа, но по умолчанию они не включены. Вы должны включить их перед миграцией.

Поддержка внешнего ключа SQLite: 2. Включение поддержки внешнего ключа

Это команда SQLite для их включения:

PRAGMA foreign_keys = ON;

Вы можете включить эту PRAGMA через Haskell и Persistent с помощью следующего кода:

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.

Поваренная книга Yesod: активировать проверка внешнего ключа в Sqlite

person MCH    schedule 10.05.2018