为了账号安全,请及时绑定邮箱和手机立即绑定

在 Heroku 部署期间使用 Go 执行 MySQL 脚本时出现 SQL 语法错误

在 Heroku 部署期间使用 Go 执行 MySQL 脚本时出现 SQL 语法错误

Go
牧羊人nacy 2022-09-05 10:45:24
我正在将一个使用Go和MySQl为数据库制作的API部署到Heroku。我正在遵循本指南并设置所有内容,但现在我正在尝试执行MySQL脚本以使用一些虚拟数据设置表。但是我经常收到错误,说脚本是错误的,即使我在本地使用它没有问题。我已经将MySQL数据库连接到Heroku环境,并且启动数据库不会引发任何错误。以下是将其部署到 Heroku 时显示错误的日志:2021-06-05T12:49:16.442359+00:00 app[web.1]: ERROR  2021/06/05 12:49:16 main.go:45: Error executing SQL script : Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'USE assessment;架构.sqlCREATE DATABASE assessment;USE assessment;CREATE TABLE users (    id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,     email VARCHAR(255) NOT NULL);INSERT INTO `users` VALUES (1,"test1@gmail.com");INSERT INTO `users` VALUES (2,"test2@gmail.com");INSERT INTO `users` VALUES (3,"test3@gmail.com");INSERT INTO `users` VALUES (4,"test4@gmail.com");INSERT INTO `users` VALUES (5,"test5@gmail.com");CREATE TABLE features (    feature_id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,    user_id INTEGER NOT NULL,    feature_name VARCHAR(100) NOT NULL,    can_access BOOLEAN NOT NULL DEFAULT FALSE,    FOREIGN KEY (user_id) REFERENCES users(id) );INSERT INTO `features` VALUES (1, 1, "automated-investing", 1);INSERT INTO `features` VALUES (2, 1, "crypto", 0);INSERT INTO `features` VALUES (3, 2, "crypto", 0);INSERT INTO `features` VALUES (4, 3, "automated-investing", 0);INSERT INTO `features` VALUES (5, 4, "automated-investing", 1);INSERT INTO `features` VALUES (7, 1, "financial-tracking", 1);INSERT INTO `features` VALUES (8, 2, "financial-tracking", 0);INSERT INTO `features` VALUES (9, 3, "financial-tracking", 1);INSERT INTO `features` VALUES (10, 4, "financial-tracking", 0);
查看完整描述

2 回答

?
潇湘沐

TA贡献1816条经验 获得超6个赞

大多数针对MySQL运行查询的接口都不支持多查询。换句话说,它们不允许用分号分隔多个 SQL 语句,每个调用只支持一个 SQL 语句。


在你的例子中,它返回了一个语法错误,因为假设输入被解析为单个语句,CREATE DATABASE语句中没有。USE ...USE


CREATE DATABASE assessment; USE assessment;

这意味着,如果要处理包含许多 SQL 语句的文件,则不能只执行正在执行的操作,并将整个文件视为一个字符串,以传递给以下各项的单个调用:Exec()


c, ioErr := ioutil.ReadFile("./schema.sql")

sqlScript := string(c)

...

_, err = db.Exec(sqlScript)

必须将该文件的内容拆分为单独的 SQL 语句,然后循环访问这些语句,一次运行每个语句。

这比听起来更复杂,因为:

  • SQL 脚本可能包含一个语句,该语句将语句之间的字符从分号更改为其他字符。DELIMITER

  • 字符串文本或注释中可能有分号。

  • 某些语句(如 CREATE 过程、CREATE 触发器等)可能在例程正文中的语句之间包含分号。您不希望这些分号成为语句的末尾,而是希望将所有内容包含在例程定义的末尾。

  • 语句本身不能由MySQL服务器执行。它只控制客户端。因此,您必须将其视为未发送到循环中的服务器的异常。实际上,还有一堆其他mysql客户端内置命令,如果您在SQL脚本中找到它们,则必须以类似的方式处理它们。DELIMITER

如果你最终对所有这些逻辑进行编码,那么你基本上已经在Go中重新实现了MySQL命令行客户端。

如果您跳过所有编码工作,只需使用os.exec.Command运行MySQL命令行客户端,它将更快,更简单。想想看 - 它将为您节省数周的编码工作,复制运行MySQL客户端中已经实现的SQL脚本的所有细微差别功能。


查看完整回答
反对 回复 2022-09-05
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

好吧,所以我决定使用Heroku提供的凭据直接连接到mysql数据库。


这将返回数据库的 URL。


heroku config | grep CLEARDB_DATABASE_URL

它看起来像这样:


mysql://alphanum-username:alphanum-password@us-cdbr-iron-east-01.cleardb.net/heroku_alphanum_name?reconnect=true

然后使用主机从URL连接到它,在本例中是。密码来自 。mysql -u username -h host -pus-cdbr-iron-east-01.cleardb.netalphanum-password


我运行了相同的查询,但收到此错误,这意味着我无法访问数据库。


ERROR 1044 (42000): Access denied for user 'bbf806af82a4c9'@'%' to database 'assessment'

“正在运行”显示可以作为用户连接到特定的数据库。show databases;


mysql> SHOW DATABASES;

+------------------------+

| Database               |

+------------------------+

| information_schema     |

| herokusdfhsdfhsdfsfsdf |

+------------------------+

从这里开始,我运行并运行了查询的其余部分,没有任何问题。USE herokusdfhsdfhsdfsfsdf


查看完整回答
反对 回复 2022-09-05
  • 2 回答
  • 0 关注
  • 136 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号