Haskell PersistentでUpperCaseなテーブルに対応する方法
大文字とアンスコで作られたテーブルに lowerCaseSetings アクセスすると、 テーブルが見つからない とOracleで叱られるパターンがあるというかあった、アクセス時にテーブル名に引用符を付けずにいけばアクセスできそうだったがやり方が分からなかったので、あきらめてテーブル名を変えてアクセスできる方法をとった。
そこでPersistentを利用してデータベースマイグレーションをかけた場合に、modelファイルにキャメルでかかれたエンテティ情報をデータベーステーブル名へ変換生成する方法を決める関数が2つある
model例
OraEmail
email Text
userId OraUserId Maybe
...
lowerCaseSettings
この関数はキャメル部分をアンスコ(_)でつけてすべて小文字で生成する
CREATE TABLE ora_email (email, user_id....
upperCaseSettings
この関数はそのままキャメルで生成する
CREATE TABLE OraEmail (email, userId....
マイグレーションから作成して利用していく分には問題ないが、既存のデータベースでテーブル名が全部大文字で作成されている場合、どちらもつかえない
大文字のテーブルに対応する
今のところ調査が中途半端で、シーケンス名や制約名などがマイグレーションで作成した場合、一部小文字になってしまうが、 マイグレーションはしない という前提であればデータベースへのアクセスは可能
fullUpperCaseSettingsの作成
オリジナルでupperCaseSettingsをパクって似たようなものをつくる、TemplateHaskellとQuasiQuoteで生成されるので外部からModel.hsへImportして使えるようにする
{-# LANGUAGE OverloadedStrings #-}
module Ext.Persist
( fullUpperCaseSettings
)where
import Data.Char
import qualified Data.Text as T
import Database.Persist.Quasi
fullUpperCaseSettings :: PersistSettings
= PersistSettings
fullUpperCaseSettings =
{ psToDBName let go c
| isUpper c = T.pack ['_', toUpper c]
| otherwise = T.singleton (toUpper c)
in T.dropWhile (=='_') . T.concatMap go
= True
, psStrictFields = "ID"
, psIdName }
そして、Importしつつこの関数をpersistFileWith関数へ渡してやる
...
import Ext.Persist
...
"migrateAll"]
share [mkPersist sqlSettings, mkMigrate $(persistFileWith fullUpperCaseSettings "config/models.persistentmodels")
...
そうすると
CREATE TABLE ORA_EMAIL (EMAIL, USER_ID....
のようなテーブルにアクセスできるようになる
Github
コードはこちら
Posted on 2021-03-20 06:43:41