Sqlboilerの設定が正しいはずなのに読み込まれない。。
Go言語でSqlboilerを採用したのですが、設定周りで結構ハマってしまってしまったので、備忘録として記載します。
TOMLの設定正しいのに、なぜか読んでくれない。このエラー出る。。って人は参考にしてください。
found key user in config, but it was not a string (<nil>)
SQLBoiler?
Go言語のORMです。
GORMと、SQLBoilerが大体有名どころみたいです。
GORMは、モデルファーストなフレームワークで評判も良さそうですが、すでにテーブル定義があったので、スキーマファーストらしいSQLBoilerをORMに使うことにしました。
使ってみる
sqlboiler.toml(yamlでもいいらしい)をルートに配置して、DBの接続設定を書くと、DBに接続してスキーマからモデルを生成してくれるツールです。
やりかたは公式のReadmeに詳しく載っています。いざ、tomlを書いて、mysqlに接続してみます。
tomlはこんな感じ。mysqlのテーブルに接続設定を書けば良いと。
TOMLの構文はこちらが詳しいです。
output = "repository/models"
pkgname = "repository"
#delete output directory if exists.
wipe = "true"
debug = "true"
[mysql]
dbname = "db-name"
host = "127.0.0.1"
port = 3306
user = "user"
pass = "pass"
sslmode = "false"
以下コマンドで生成!
sqlboiler mysql
すると。。。
found key user in config, but it was not a string (<nil>)
ええ、、
なんでやねん。
-dをつけて、デバック実行とやらをやってみると、
{
"config": {
"driver_name": "mysql",
"driver_config": {
"blacklist": null,
"dbname": null,
"host": null,
"pass": null,
"port": null,
"sslmode": null,
"user": null,
"whitelist": null
},
"pkg_name": "repository",
"out_folder": "models",
"debug": true,
"wipe": true,
"struct_tag_casing": "snake",
"relation_tag": "-",
"imports": {
"all": {
"Standard": [
"\"database/sql\"",
"\"fmt\"",
"\"reflect\"",
"\"strings\"",
"\"sync\"",
"\"time\""
],
"ThirdParty": [
"\"github.com/friendsofgo/errors\"",
"\"github.com/volatiletech/sqlboiler/v4/boil\"",
"\"github.com/volatiletech/sqlboiler/v4/queries\"",
"\"github.com/volatiletech/sqlboiler/v4/queries/qm\"",
"\"github.com/volatiletech/sqlboiler/v4/queries/qmhelper\"",
"\"github.com/volatiletech/strmangle\""
]
},
"test": {
"Standard": [
"\"bytes\"",
"\"reflect\"",
"\"testing\""
],
"ThirdParty": [
"\"github.com/volatiletech/sqlboiler/v4/boil\"",
"\"github.com/volatiletech/sqlboiler/v4/queries\"",
"\"github.com/volatiletech/randomize\"",
"\"github.com/volatiletech/strmangle\""
]
},
"singleton": {
"boil_queries": {
"Standard": null,
"ThirdParty": [
"\"github.com/volatiletech/sqlboiler/v4/drivers\"",
"\"github.com/volatiletech/sqlboiler/v4/queries\"",
"\"github.com/volatiletech/sqlboiler/v4/queries/qm\""
]
},
"boil_types": {
"Standard": [
"\"strconv\""
],
"ThirdParty": [
"\"github.com/friendsofgo/errors\"",
"\"github.com/volatiletech/sqlboiler/v4/boil\"",
"\"github.com/volatiletech/strmangle\""
]
}
},
"test_singleton": {
"boil_main_test": {
"Standard": [
"\"database/sql\"",
"\"flag\"",
"\"fmt\"",
"\"math/rand\"",
"\"os\"",
"\"path/filepath\"",
"\"strings\"",
"\"testing\"",
"\"time\""
],
"ThirdParty": [
"\"github.com/spf13/viper\"",
"\"github.com/volatiletech/sqlboiler/v4/boil\""
]
},
"boil_queries_test": {
"Standard": [
"\"bytes\"",
"\"fmt\"",
"\"io\"",
"\"io/ioutil\"",
"\"math/rand\"",
"\"regexp\""
],
"ThirdParty": [
"\"github.com/volatiletech/sqlboiler/v4/boil\""
]
},
"boil_suites_test": {
"Standard": [
"\"testing\""
],
"ThirdParty": null
}
}
},
"aliases": {},
"version": "4.4.0"
},
"driver_config": {
"blacklist": null,
"dbname": null,
"host": null,
"pass": null,
"port": null,
"sslmode": null,
"user": null,
"whitelist": null
},
"schema": "",
"dialect": {
"lq": 0,
"rq": 0,
"use_index_placeholders": false,
"use_last_insert_id": false,
"use_schema": false,
"use_default_keyword": false,
"use_auto_columns": false,
"use_top_clause": false,
"use_output_clause": false,
"use_case_when_exists_clause": false
},
"tables": null,
"templates": null
}
おう、driver_configが全部null。。。
Issuesとか調べてみると
PSQLで設定ファイル読まれません
まったく同じ現象!
この人はPSQLだけど。。
とりあえずお前の環境がおかしい言われてクローズされてます。
環境変数がどうのこうのとあるので、やっぱり変な設定ファイル読みに行っている可能性が高いということで、SQLBoilerのコードをちょっとみてみることに。。
##結果、環境変数気をつけるべし
コードを追っかけた結果、原因がわかりました。
sqlboilerのmain.go,270行目(記事執筆時点です。)にこんなコードがあります。
これ、psqlとかmysqlとか書いてあるtomlのテーブルの値を読みに行って、コマンドに渡すところなのですが、ここで、環境変数もみています。
func allKeys(prefix string) []string {
fmt.Printf("Call allKeys:" + prefix)
keys := make(map[string]bool)
prefix += "."
for _, e := range os.Environ() {
splits := strings.SplitN(e, "=", 2)
key := strings.ReplaceAll(strings.ToLower(splits[0]), "_", ".")
if strings.HasPrefix(key, prefix) {
keys[strings.ReplaceAll(key, prefix, "")] = true
}
}
for _, key := range viper.AllKeys() {
fmt.Fprintln(os.Stderr, "viper key:", key)
if strings.HasPrefix(key, prefix) {
keys[strings.ReplaceAll(key, prefix, "")] = true
}
}
keySlice := make([]string, 0, len(keys))
for k := range keys {
keySlice = append(keySlice, k)
}
return keySlice
}
僕は環境変数に、$MYSQLという変数がありまして、その値をどうやら読んでしまって、おかしくなっていたらしい。
とりあえずMYSQLという名前があるとここで引っかかるので、名前を変更して、実行したら、とおりました。。
結構ハマってしまった。
SQLBoiler使う時は環境変数名気をつけた方がいいですよという話でした。
殴り書きですみません。
Issueの人もPSQLという環境変数用意しちゃっていたみたいですね。