yesodweb/persistent
SQLite: FOREIGN KEY constraint failed when migrating
Offen
#1.125 geöffnet am 18.09.2020
good first issue
Repository-Metriken
- Stars
- (484 Sterne)
- PR-Merge-Metriken
- (PR-Metriken ausstehend)
Beschreibung
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
import Database.Persist.Sqlite
import Database.Persist.TH
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
-- Uncomment this line in the second run
-- age Int Maybe
deriving Show
BlogPost
title String
authorId PersonId
deriving Show
|]
main :: IO ()
main = runSqlite "db" $ do
runMigration migrateAll
-- Comment this line in the second run
johnId <- insert $ Person "John Doe"
-- Uncomment this line in the second run
-- johnId <- insert $ Person "John Doe" $ Just 35
insert $ BlogPost "post" johnId
pure ()
stack ghcthe script above and run.- Edit the script, uncomment 2 lines and comment 1 line.
stack ghcthe script and run again.- You will see:
Migrating: CREATE TEMP TABLE "person_backup"("id" INTEGER PRIMARY KEY,"name" VARCHAR NOT NULL,"age" INTEGER NULL)
Migrating: INSERT INTO "person_backup"("id","name") SELECT "id","name" FROM "person"
Migrating: DROP TABLE "person"
main: SQLite3 returned ErrorConstraint while attempting to perform step: FOREIGN KEY constraint failed
The correct way to do migrations in SQLite is documented here: https://sqlite.org/lang_altertable.html#making_other_kinds_of_table_schema_changes
In short, you need to disable foreign keys temporarily using PRAGMA commands when migrating. But this seems impossible because I can only send raw commands inside an automatically started transaction. And inside a transaction, PRAGMA foreign_keys=OFF has no effect.
Could you please change the logic of runMigration so that it follows the 12 steps in SQLite document precisely?