Я пробовал решения из других ответов, но до сих пор никто не решил:
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();
И, наконец, я установил его в runtime-conf.xml в Propel:
<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
список временных файлов PHP, созданных при загрузке файлов с Amazon S3 Имена файлов выглядят так: /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,
)
);
Самые полезные связанные вопросы:
Единственное место, где можно установить 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\' (...);"');
Основано на этот ответ.