我有一些在本地GAE服务器上运行的代码,但是一旦将其发布到GAE,它就会引发错误"驱动程序:连接错误"。
下面的代码生成一个新的* sql.DB:
1 2 3 4 5 6 7 8 | func NewDb() (*sql.DB, error) { cloud := os.Getenv("dbcloud") local := os.Getenv("dblocal") if appengine.IsDevAppServer() { return sql.Open("mysql","root@tcp("+local+":3306)/dbo") } return sql.Open("mysql","root@cloudsql("+cloud+")/dbo") } |
在我的app.yaml中,我有以下内容:
1 2 3 | env_variables: dbcloud: 'projectid:instancename' dblocal: 'xxx.xxx.xxx.xxx' |
看来正确返回了一个新的* sql.DB,但是一旦我开始使用准备好的语句,事情就会开始崩溃。
1 2 | db, err := NewDb() // err is nil stmt, err := db.Prepare("INSERT INTO dbo.Users (Id) VALUES (?)") // err is driver: bad connection |
我已经为此战斗了一个小时,我可能正在做一些非常愚蠢的事情,任何帮助将不胜感激!
-
您是否正在使用go-sql-driver(
"github.comgo-sql-drivermysql" )或mymysql驱动程序("github.comziutekmymysqlgodrv" )? - github.com/go-sql??-driver/mysql,我需要在GAE中使用github.com/ziutek??/mymysql/godrv吗?
-
不,两者都可以与Cloud SQL一起很好地工作,但是它们需要不同的语法来定义数据源。但是,您看起来不错,您确定用户为
root ,并且项目ID和实例名称正确吗? - 是的,只有当前用户是root用户(我使用本地GAE服务器通过IP连接到Cloud SQL实例,并且运行良好),并且已经多次检查项目ID /实例名称,它们相同,所以我看不到是问题所在。
- 您的应用程序和Cloud SQL实例是否位于同一区域?您是否已授予应用访问SQL实例的权限?
- 是的,它们都是我们中心的,并且它们都在同一个项目中,因此我认为它们默认情况下具有访问权限,这脱离了SQL实例的访问控制:" App Engine授权默认情况下,该项目中的所有应用程序都经过授权。要在其他项目,请按照以下步骤操作。"
- 请参阅此页面如何授予访问权限:从Google App Engine连接(注意:第一代和第二代实例的不同步骤)。
- 是的,我已经看到,在询问这里我当前正在使用Gen 2之前,第一步是:"如果您的应用程序与Cloud SQL实例位于同一项目中,则可以继续执行步骤2。"哪一个给您连接代码?我唯一不了解的是sql.Open不会导致错误,但是之后尝试使用db会吗?
-
那很正常。
sql.Open() 仅验证其参数,但不会打开连接。为此,您可以使用DB.Ping() 。有关详细信息,请参见以下答案:为什么sql.Open()不应返回nil作为错误? - 嘿@icza发现了问题!我需要将dbcloud env_variable更改为包括我的区域,即使它们都在us_central中?因此,现在它进入了projectid:regionname:instancename并可以工作了……非常感谢您的宝贵时间,尽管这对我来说只是一个愚蠢的错误!
- 很高兴您解决了您的问题。请发布您的解决方案作为答案,以便其他人可以从中受益。
我最终需要更改我的dbcloud变量,以包括从以下位置将其更改的SQL Server的区域:
1 | 'projectid:instancename' |
至:
1 | 'projectid:regionname:instancename' |
不知道为什么我需要这样做,因为它不在https://github.com/go-sql-driver/mysql的文档中,但现在都可以使用!