为什么我在 Laravel 中使用 "SOURCE [filename]" 时收到 MySQL 语法错误 1064,而当我从命令行运行相同的完全相同的命令时却没有?



我将Laravel与Homestead和MySQL一起使用。我有一个数据库转储文件,我想按命令还原它。当我从命令行运行这个时,我没有得到任何错误:

mysql -h localhost -u homestead -psecret homestead < /home/vagrant/Data/local-db-reset.sql

我的local-db-reset.sql文件读取:

DROP DATABASE IF EXISTS homestead;
CREATE DATABASE homestead;
USE homestead;
SOURCE /home/vagrant/Data/local-db-snapshot.sql;

然而,当我在PHP中从自定义的artisan命令中运行相同的命令时,我会从MySQL中得到语法错误1064:

$db = 'homestead';
$snapshot = '/home/vagrant/Data/local-db-snapshot.sql;';
DB::transaction(function() use ($db, $snapshot) {
DB::statement('DROP DATABASE IF EXISTS ' . $db . ';');
DB::statement('CREATE DATABASE ' . $db . ';');
DB::statement('USE ' . $db . ';');
DB::statement('SOURCE ' . $snapshot . ' ;');
});

确切的错误为:

IlluminateDatabaseQueryException  : SQLSTATE[42000]: Syntax error or access violation: 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 'SOURCE /home/vagrant/Data/local-db-snapshot.sql' at line 1 (SQL: /home/vagrant/Data/local-db-snapshot.sql ;)

1064错误是由SOURCE命令触发的,即使它的计算结果与上面的sql脚本中的命令完全相同。为什么?我该如何解决这个问题?我需要能够从一个手工命令,或者至少从php的某个地方完成这项工作。

请注意,我不认为artisan migrate:fresh是一种选择,所以请忘记这种方法。我真的需要恢复这个精确的快照。

我的一位同事指出,SOURCE不是SQL命令,它只是mysql命令行客户端的元命令。因此,我(本质上(重构了我的代码,使用shell_exec()和上面最顶部的原始mysql命令行命令,现在一切都正常了。

这可能是因为您的Web服务器使用的用户与您在控制台中使用的用户不同。

我自己不使用Homestead,但在我的设置中,Apache在用户www数据下运行。

您可以通过临时更改.sql文件的权限来进行检查:

chmod 777 /home/vagrant/Data/local-db-snapshot.sql

如果这解决了问题,您需要计算出您的Web服务器正在使用的用户。您应该能够通过运行sudo ps aux | grep nginx来做到这一点。

这应该会输出这样的东西(注意:为了适应我的设置,我用nginx代替了apache(:

joundill@machine:~$ sudo ps aux | grep apache
root        1099  0.0  1.0 243836 40600 ?        Ss   00:46   0:00 /usr/sbin/apache2 -k start
www-data    3395  0.0  2.4 253292 96744 ?        S    01:36   0:01 /usr/sbin/apache2 -k start
joundill    4850  0.0  0.0   6436   672 pts/0    S+   02:11   0:00 grep --color=auto apache
joundill@machine:~$ 

正如您所看到的,用户www数据正在运行apache(在您的例子中是nginx(。您需要授予此用户对.sql文件的访问权限。

最新更新