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物語はこちら
もうちょい綺麗なやり方あんのかなぁ...
0 件のコメント:
コメントを投稿