お題
前回の記事で提示したソースにコメントは書いていたのだけど、ちょっとハマったので別途記事にしておこう。
GAE試行Index
- GAE/Go1.11試行(その3:「GoでMVC+S構成のWebAPIを作る」)
- GAE/Go1.11試行(その2:「"google.golang.org/appengine"パッケージのappengineから取れる情報」)
- GAE/Go1.11試行(その1:「クイックスタート」)
- GAE/Go1.9試行(その0:「クイックスタート」)
開発環境
# OS
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="17.10 (Artful Aardvark)"
# Golang
$ go version
go version go1.11.2 linux/amd64
バージョンの切り替えはgoenvで行っている。
# gcloud
$ gcloud version
Google Cloud SDK 227.0.0
前提
- スタンダード環境での開発とする。
- GCPプロジェクトは作成済み。
- gcloudコマンドインストール済み。
実践
GAE/Goのスタンダード環境におけるCloud SQL接続方法(Go v1.9の場合)
下記によると、「 【ユーザ名】:【パスワード】@cloudsql(【インスタンス接続文字列】)/
」。
※インスタンス接続文字列は「 【プロジェクトID】:【リージョン】:【インスタンス】
」
https://cloud.google.com/appengine/docs/standard/go/cloud-sql/using-cloud-sql-mysql
上記、データベース名については記載がないのだけど、おそらく「 【ユーザ名】:【パスワード】@cloudsql(【インスタンス接続文字列】)/【データベース名】
」。
例えば gorm を使って接続するコードは下記のような感じ。
db, err := gorm.Open("mysql", "testuser:testpass@cloudsql(testproj:asia-northeast1:testinstance)/testdb")
これを、同じスタンダード環境ということで Go v1.11 でも同じコードで接続を試みると、下記のように接続エラーとなる。
panic: dial cloudsql: unknown network cloudsql
goroutine 1 [running]:
main.main()
/tmp/staging326508706/srv/main.go:20 +0x380
GAE/Goのスタンダード環境におけるCloud SQL接続方法(Go v1.11の場合)
Go v1.11では下記にあるように、同じスタンダード環境でも v1.9 とはCloud SQLへの接続文字列が異なる。
https://cloud.google.com/appengine/docs/standard/go111/using-cloud-sql#running_the_sample_code
runtime: go111
env_variables:
# Replace INSTANCE_CONNECTION_NAME with the value obtained when configuring your
# Cloud SQL instance, available from the Google Cloud Console or from the Cloud SDK.
# For Cloud SQL 2nd generation instances, this should be in the form of "project:region:instance".
CLOUDSQL_CONNECTION_NAME: INSTANCE_CONNECTION_NAME
〜省略〜
var (
connectionName = mustGetenv("CLOUDSQL_CONNECTION_NAME")
〜省略〜
)
〜省略〜
if socket == "" {
socket = "/cloudsql"
}
// MySQL Connection, comment out to use PostgreSQL.
// connection string format: USER:PASSWORD@unix(/cloudsql/)PROJECT_ID:REGION_ID:INSTANCE_ID/[DB_NAME]
dbURI := fmt.Sprintf("%s:%s@unix(%s/%s)/", user, password, socket, connectionName)
conn, err := sql.Open("mysql", dbURI)
正直、読み解きづらい・・・と自分は感じたのだけど、どうだろう・・・?(コメントに記載されたフォーマットが微妙にコードのフォーマットと異なっていてトラップだし。)
ちなみに、以下のように書くとCloud SQLに接続成功。
db, err := gorm.Open("mysql", "testuser:testpass@unix(/cloudsql/testproj:asia-northeast1:testinstance)/testdb")
ローカルとGAE環境との接続文字列切り替え
ローカルではMySQLにつないでGAE環境ではCloud SQLにつなぎたい場合はこんな感じにするといいかな。
runtime: go111
env_variables:
# For Cloud SQL 2nd generation instances, this should be in the form of "project:region:instance".
CLOUDSQL_CONNECTION_NAME: 【プロジェクトID】:asia-northeast1:testinstance
CLOUDSQL_USER: testuser
CLOUDSQL_PASSWORD: testpass
CLOUDSQL_DATABASE: testdb
〜省略〜
func main() {
var (
connectionName = os.Getenv("CLOUDSQL_CONNECTION_NAME")
user = os.Getenv("CLOUDSQL_USER")
password = os.Getenv("CLOUDSQL_PASSWORD")
database = os.Getenv("CLOUDSQL_DATABASE")
)
db, err := gorm.Open("mysql", fmt.Sprintf("%s:%s@unix(/cloudsql/%s)/%s", user, password, connectionName, database))
if appengine.IsDevAppServer() {
db, err = gorm.Open("mysql", "testuser:testpass@tcp(127.0.0.1:3306)/testdb?charset=utf8&parseTime=True&loc=Local")
}
if err != nil {
panic(err)
}
defer db.Close()
〜省略〜
まとめ
新しものを試すというのは、こういう(当然なんだけど)英語ドキュメントを臆することなく読む必要があり、
かつ、微妙なドキュメントの読みにくさとの戦いでもある。
いや、自分の読解力を棚に上げていることは重々承知・・・。