17
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

GAE/Go1.11試行(その4:「CloudSQL接続方法」)

Posted at

お題

前回の記事で提示したソースにコメントは書いていたのだけど、ちょっとハマったので別途記事にしておこう。

GAE試行Index

開発環境

# 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につなぎたい場合はこんな感じにするといいかな。

[app.yaml]
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()

 〜省略

まとめ

新しものを試すというのは、こういう(当然なんだけど)英語ドキュメントを臆することなく読む必要があり、
かつ、微妙なドキュメントの読みにくさとの戦いでもある。
いや、自分の読解力を棚に上げていることは重々承知・・・。

17
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?