代码之家  ›  专栏  ›  技术社区  ›  NobleUplift

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

  •  1
  • NobleUplift  · 技术社区  · 10 年前

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

    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 是从AmazonS3下载文件创建的临时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 回复  |  直到 7 年前
        1
  •  1
  •   O. Jones    10 年前

    唯一可以设置 PDO::MYSQL_ATTR_LOCAL_INFILE 把某事归因于某人 true 在构建时 一个新的 Connection 手柄您正在尝试在构造句柄后进行设置: getConnection() 方法只需从Propel运行时检索句柄。

    Propel似乎在盖子下面构造了把手。

    在不更改Propel的源代码的情况下,您最好的选择是直接使用PDO创建自己的连接句柄,然后执行 LOAD DATA INFILE ,然后关闭该手柄。换言之,绕着行走进行大容量装载操作。

        2
  •  -1
  •   Community CDub    7 年前

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

    $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 .