如何在Propel中启用LOAD DATA LOCAL INFILE?

时间:2015-02-04 15:27:17

标签: php mysql amazon-s3 propel load-data-infile

我尝试过其他答案的解决方案,但到目前为止还没有解决:

PDOException 42000 SQLSTATE[42000]: Syntax error or access violation: 
1148 The used command is not allowed with this MySQL version

我正在使用PropelPDO准备查询。我试过了:

$cnct = \Propel::getConnection();
$cnct->setAttribute(\PDO::MYSQL_ATTR_LOCAL_INFILE, true);

但这并没有阻止错误,所以我也尝试过:

$prepare = $cnct->prepare($sql, array(
    \PDO::MYSQL_ATTR_LOCAL_INFILE => true,
));
$prepare->execute();

最后,我将它设置在Propel的runtime-conf.xml中:

<options>
    <option id="MYSQL_ATTR_LOCAL_INFILE">true</option>
</options>

我也尝试将其定义为属性:

<attributes>
    <option id="MYSQL_ATTR_LOCAL_INFILE">true</option>
</attributes>

以下是尝试使用此命令的代码块:

foreach ($files as $filename => $file) {
    error_log('[' . date('Y-m-d h:i:s') . '] Importing ' . $filename . '... ');
    $sql = <<<SQL
LOAD DATA LOCAL INFILE '$filename' REPLACE 
INTO TABLE `my_table`  
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '\"' 
LINES TERMINATED BY '\n' 
(...);
SQL;
    error_log($sql);
    $prepare = $cnct->prepare($sql, array(
        \PDO::MYSQL_ATTR_LOCAL_INFILE => true,
    ));
    $prepare->execute();
}

$files是从Amazon S3下载文件而创建的临时PHP文件列表。文件名如下所示:/tmp/php7U5bgd

我无法访问my.cnf。相同的数据库和用户允许LOAD DATA LOCAL INFILE在Java中运行。我也使用了MySQL CLI,它允许我运行这个命令。

这可以防止抛出PDOException,但它不会将任何数据保存到我的数据库中:\

$conf = include 'runtime-conf.php';
$cnct = new \PDO(
    $conf['datasources']['my_database']['connection']['dsn'], 
    $conf['datasources']['my_database']['connection']['user'], 
    $conf['datasources']['my_database']['connection']['password'], 
    array(
        \PDO::MYSQL_ATTR_LOCAL_INFILE => true,
    )
);

最有帮助的相关问题:

  1. LOAD DATA LOCAL INFILE forbidden in... PHP
  2. MySQL: Enable LOAD DATA LOCAL INFILE

2 个答案:

答案 0 :(得分:1)

在构建新的PDO::MYSQL_ATTR_LOCAL_INFILE句柄时,将true属性设置为Connection的唯一有效位置是。您在构造句柄后尝试设置它:getConnection()方法只是从Propel运行时检索句柄。

Propel似乎在封面下构建了这个句柄。

在不更改Propel的源代码的情况下,您最好的选择是直接使用PDO创建自己的连接句柄,然后执行LOAD DATA INFILE,然后关闭该句柄。换句话说,绕过Propel进行批量加载操作。

答案 1 :(得分:-1)

这是唯一对我有用的解决方案:

$conf = include 'runtime-conf.php';

$dsn = $conf['datasources']['adstudio']['connection']['dsn'];
$user = $conf['datasources']['adstudio']['connection']['user'];
$password = $conf['datasources']['adstudio']['connection']['password'];

$hoststart = strpos($dsn, 'host=') + 5;
$hostend = strpos($dsn, ';', $hoststart);
$hostname = substr($dsn, $hoststart, $hostend - $hoststart);

$portstart = strpos($dsn, 'port=') + 5;
$portend = strpos($dsn, ';', $portstart);
$port = substr($dsn, $portstart, $portend - $portstart);

exec('mysql -h ' . $hostname . ' -P ' . $port . ' -u ' . $user . ' ' .
    '-p' . $password . ' --local-infile=1 ' .
    '-e "USE my_database;LOAD DATA LOCAL INFILE \'' . $tmp . '\' REPLACE INTO TABLE my_table FIELDS TERMINATED BY \',\' OPTIONALLY ENCLOSED BY \'\\"\' LINES TERMINATED BY \'\n\' (...);"');

基于this answer