LOAD DATA LOCAL INFILE失败 - 从php到mysql(在Amazon rds上)

Red*_*arf 7 php mysql amazon-rds load-data-infile

我们将数据库从在Web服务器上移动到单独的服务器(从Amazon EC2 Web服务器到RDS实例).

我们有一个LOAD DATA INFILE,在此之前需要添加LOCAL关键字,因为数据库将位于与Web服务器不同的机器上.

在我的开发服务器上测试,结果证明它不起作用:

  • 我仍然可以从php中加载数据INFILE
  • 我可以从mysql命令行加载DATA LOCAL INFILE(使用--local_infile = 1)
  • 我无法从php加载DATA LOCAL INFILE.

在那两个有用的东西之间,它排除了:

  • sql或php代码的问题
  • 上传文件存在问题,包括语法和文件权限
  • mysql服务器设置问题

我得到的错误是:ERROR 1148(42000):这个MySQL版本不允许使用命令(如果我不使用--local_infile = 1,我从mysql命令行中得到错误)


其他一些相关信息:

  • Ubuntu 12.04,mysql 5.5.24,php 5.3.10
  • 我正在使用php的mysql_connect(而不是mysqli,因为我们计划使用facebook的hiphop编译器,它不支持mysqli.)
  • 因此,connect命令需要设置一个额外的标志:

    mysql_connect($dbHost, $dbUser, $dbPass, false, 128);
    
    Run Code Online (Sandbox Code Playgroud)
  • 我用phpinfo()来证实这一点 mysql.allow_local_infile = On
  • 我在Amazon RDS上尝试过(如果它是我的开发服务器中的一个问题),它也不能在那里工作.(打开local_infile参数.)

关于我没有尝试的唯一的事情就是在我的开发服务器上编译mysql服务器,打开标志以允许本地infile ...但即使我在我的开发服务器上运行它也不会帮助我使用Amazon RDS.(除此之外,LOAD DATA LOCAL INFILE可以在mysql命令行中运行.)


看起来这是php的mysql_connect()的具体问题

任何使用LOAD DATA LOCAL INFILE(可能来自Amazon RDS)知道让这个工作的诀窍的人?

Red*_*arf 9

我已经放弃了这个,因为我认为它是php中的一个错误 - 特别是mysql_connect代码,现在已经弃用了.它可能通过使用与@eggyal提到的错误报告中提到的步骤类似的步骤自行编译php来解决:https://bugs.php.net/bug.php id = 54158

相反,我将通过执行system()调用并使用mysql命令行来解决它:

$sql = "LOAD DATA LOCAL INFILE '$csvPathAndFile' INTO TABLE $tableName FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\\\"' ESCAPED BY '\\\\\\\\' LINES TERMINATED BY '\\\\r\\\\n';";
system("mysql -u $dbUser -h $dbHost --password=$dbPass --local_infile=1 -e \"$sql\" $dbName");
Run Code Online (Sandbox Code Playgroud)

这对我有用.


pac*_*nka 7

这是一个清单,以排除这个讨厌的错误:


1-在MySQL中授予用户FILE权限,phpMyAdmin通常不包括此权限:

GRANT FILE ON *.* TO 'db_user'@'localhost';
Run Code Online (Sandbox Code Playgroud)

2-在/ etc/mysql /或你的mysql路径中编辑my.cnf:

[mysql]
local-infile=1
[mysqld]
local-infile=1
Run Code Online (Sandbox Code Playgroud)

3-在/ etc/php5/cli /或类似的php.ini中:

mysql.allow_local_infile = On
Run Code Online (Sandbox Code Playgroud)

您可以选择ini_set在脚本中运行:

ini_set('mysql.allow_local_infile', 1);
Run Code Online (Sandbox Code Playgroud)

4-数据库处理程序库必须使用正确的选项.
PDO:

new PDO('mysql:host='.$db_host.'.;dbname='.$db_name, $db_user, $db_pass,
array(PDO::MYSQL_ATTR_LOCAL_INFILE => 1));
Run Code Online (Sandbox Code Playgroud)

mysqli:

$conn = mysqli_init();
mysqli_options($conn, MYSQLI_OPT_LOCAL_INFILE, true);
mysqli_real_connect($conn,server,user,code,database);
Run Code Online (Sandbox Code Playgroud)

5-确保INFILE命令使用文件的绝对路径并且它存在:

$sql = "LOAD DATA INFILE '".realpath(is_file($file))."'";
Run Code Online (Sandbox Code Playgroud)

6-检查PHP和MySQL是否可以读取目标文件和父目录.

$ sudo chmod 777 file.csv
Run Code Online (Sandbox Code Playgroud)

7-如果您在本地工作,可以LOCAL从SQL中删除:

LOAD DATA INFILE
Run Code Online (Sandbox Code Playgroud)

代替:

LOAD DATA LOCAL INFILE
Run Code Online (Sandbox Code Playgroud)

注意:如果编辑其配置文件,请记住重新启动MySQL和PHP服务.

希望这有助于某人.


Kri*_*aan 5

正如提到这个岗位,增加第三和第四参数的mysql_connect都需要得到加载本地DATA INFILE工作.它帮助了我.任何其他建议(apparmor,my.cnf中的local-infile = 1在互联网上广泛讨论)都无济于事.以下PHP代码为我工作!

mysql_connect(HOST,USER,PASS,false,128);
Run Code Online (Sandbox Code Playgroud)

没错,这也是手动的.