Persistentでsequenceの扱い
Persistentからデータベースにテーブルやらを作成すると、自動でidと言う名前でサロゲートキーが生成される。 これなら簡単にinsertできる、insertしたエンティティの自動採番されたidを返してくる。share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Person
name String
age Int Maybe
deriving Show
|]
...
...
uid <- insert $ Person "Mac" $ Just 20
...
これはこれでいいのですが、既にシーケンスとかあって、それから採番している場合、モデルの書き方が変わってちょっと面倒くさくなる。
こんな感じ...
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
NiceGuy
niceGuyId Int sqltype=bigint default=nextval('nice_guy_id_seq')
name Text
age Int
authorizedDate Day Maybe sqltype=date
regTime UTCTime sqltype=timestamptz
Primary niceGuyId
deriving Show
NiceGuyPet
name Text
niceGuyId NiceGuyId
deriving Show
insertのときniceGuyNiceGuyIdにIntを要求されて「ウゼェー」ってなる
シーケンスを手動でとる
小一時間ほどPersistentまわりを調べたのですがあまりいいやり方が見つからなかったので適当に解決した
getNiceGuySeq :: MonadIO m => ReaderT SqlBackend m [Single Int]
getNiceGuySeq = rawSql "select nextval('nice_guy_id_seq')" []
Singleの中にシーケンスが入って返ってくる
動かした後のデータベースの中身はこちら
$ stack run
Migrating: CREATe TABLE "nice_guy"( PRIMARY KEY ("nice_guy_id"),"nice_guy_id" bigint NOT NULL DEFAULT nextval('nice_guy_id_seq'),"name" VARCHAR NOT NULL,"age" INT8 NOT NULL,"authorized_date" date NULL,"reg_time" timestamptz NOT NULL)
Migrating: CREATe TABLE "nice_guy_pet"("id" SERIAL8 PRIMARY KEY UNIQUE,"name" VARCHAR NOT NULL,"nice_guy_id" INT8 NOT NULL)
Migrating: ALTER TABLE "nice_guy_pet" ADD CONSTRAINT "nice_guy_pet_nice_guy_id_fkey" FOREIGN KEY("nice_guy_id") REFERENCES "nice_guy"("nice_guy_id")
insert nice_guy__id: NiceGuyKey {unNiceGuyKey = 1} / nice_guy_pet_id: NiceGuyPetKey {unNiceGuyPetKey = SqlBackendKey {unSqlBackendKey = 1}}
insert nice_guy__id: NiceGuyKey {unNiceGuyKey = 2} / nice_guy_pet_id: NiceGuyPetKey {unNiceGuyPetKey = SqlBackendKey {unSqlBackendKey = 2}}
insert nice_guy__id: NiceGuyKey {unNiceGuyKey = 3} / nice_guy_pet_id: NiceGuyPetKey {unNiceGuyPetKey = SqlBackendKey {unSqlBackendKey = 3}}
$ psql -U sample sampledb
psql (9.6.12)
Type "help" for help.
sampledb=>
sampledb=> \d
List of relations
Schema | Name | Type | Owner
--------+---------------------+----------+--------
public | nice_guy | table | sample
public | nice_guy_id_seq | sequence | sample
public | nice_guy_pet | table | sample
public | nice_guy_pet_id_seq | sequence | sample
(4 rows)
sampledb=> select * from nice_guy;
nice_guy_id | name | age | authorized_date | reg_time
-------------+------------+-----+-----------------+-------------------------------
1 | 玉輿平八郎 | 55 | 2019-03-31 | 2019-03-31 14:11:05.500591+09
2 | 骨川筋太郎 | 47 | 2019-03-31 | 2019-03-31 14:11:05.517138+09
3 | 裏筋太郎 | 75 | 2019-03-31 | 2019-03-31 14:11:05.525973+09
(3 rows)
sampledb=> select * from nice_guy_pet;
id | name | nice_guy_id
----+----------+-------------
1 | モッコ | 1
2 | めん | 2
3 | スージー | 3
(3 rows)
こんな感じ
全部のサンプルコードはgithubへあげておきます、興味のある方はどうぞ。
empty yoshidaとPersistent物語はこちら
もうちょい綺麗なやり方あんのかなぁ...