如何在 Propel 中启用 LOAD DATA LOCAL INFILE?
How do I enable LOAD DATA LOCAL INFILE in Propel?
我尝试了其他答案的解决方案,但到目前为止 none 已经解决:
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的运行time-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,
)
);
最有帮助的相关问题:
- LOAD DATA LOCAL INFILE forbidden in... PHP
- MySQL: Enable LOAD DATA LOCAL INFILE
将 PDO::MYSQL_ATTR_LOCAL_INFILE
属性设置为 true
的唯一有效位置是 在构造 新的 Connection
句柄时。您试图在构造句柄后设置它:getConnection()
方法只是从 Propel 运行时检索句柄。
Propel 似乎在幕后构建了该手柄。
在不更改 Propel 源代码的情况下,您最好的选择是直接使用 PDO 创建您自己的连接句柄,然后执行您的 LOAD DATA INFILE
,然后关闭该句柄。换句话说,绕过 Propel 进行此批量加载操作。
这是唯一对我有用的解决方案:
$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.
我尝试了其他答案的解决方案,但到目前为止 none 已经解决:
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的运行time-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,
)
);
最有帮助的相关问题:
- LOAD DATA LOCAL INFILE forbidden in... PHP
- MySQL: Enable LOAD DATA LOCAL INFILE
将 PDO::MYSQL_ATTR_LOCAL_INFILE
属性设置为 true
的唯一有效位置是 在构造 新的 Connection
句柄时。您试图在构造句柄后设置它:getConnection()
方法只是从 Propel 运行时检索句柄。
Propel 似乎在幕后构建了该手柄。
在不更改 Propel 源代码的情况下,您最好的选择是直接使用 PDO 创建您自己的连接句柄,然后执行您的 LOAD DATA INFILE
,然后关闭该句柄。换句话说,绕过 Propel 进行此批量加载操作。
这是唯一对我有用的解决方案:
$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.