为了账号安全,请及时绑定邮箱和手机立即绑定

通过 CSV 导出/导入 mysql json 对象

通过 CSV 导出/导入 mysql json 对象

PHP
慕尼黑5688855 2023-04-15 10:40:46
我正在使用一对 PHP 脚本。一个脚本从 MYSQL 数据库读取数据并将其导出到 csv 文件,然后第二个脚本使用 csv 将导出的 csv 文件上传到另一个 MySQL 数据库实例。数据库表 A(导出)和 B(导入)的结构相同。这些脚本适用于“普通”MySQL 表和列类型。但是,当我们将它们应用于在其中一个列(MySQL 列类型为“json”)中存储 JSON 对象的 MySQL 表时,导入失败。导出数据的脚本按预期工作,生成一个 CSV 文件,其中 JSON 对象被双引号括起来……就像行中的其他值一样。导出的 CSV 文件中的行如下所示(最后一项是复杂的 json 对象,为简单起见缩写):"894","Somebody","Related","2020-02-20","{"name1":"value1","name2":"value2","name3":"value3"}","expired"在导出数据的 PHP 脚本中,它本质上是这样的:$rowStr =   "894","Somebody","Related","2020-02-20","{"name1":"value1","name2":"value2","name3":"value3"}","expired";file_put_contents($filepath, trim($rowStr), FILE_APPEND);导出没有问题。行按预期出现在 CSV 文件中(与上述格式相同)。我将 csv 读入另一个数据库的代码如下所示:    $allRows = array_map('str_getcsv',file($fp)); // read the exported csv file where $fp is the path to the file    foreach($allRows as $i => $row) {        //get the col_names from the 2nd database table (identical to the first) where $ac-> is the class that handles data queries        $col_names = $ac->get_table_column_names('databasename',$tablename);        $update_arr = array();        foreach($col_names as $i => $cname) {            $update_arr[$cname['COLUMN_NAME']] = $val;                      }        //and write the row to the 2nd db's table        $ac->create_update_table($update_arr,$tablename,FALSE);   }而且,如果重要的话,这里是“get_table_column_names”和“create_update_table”函数中使用的查询:get_table_column_names //使用PDOSELECT COLUMN_NAME,COLUMN_DEFAULT,DATA_TYPE FROM information_schema.columns WHERE table_schema = :db AND table_name = :table创建更新表INSERT INTO 'tablename' (field1, field2, field3, field4,json_object_column) VALUES ("894","Somebody","Related","2020-02-20","{"name1":"value1","name2":"value2","name3":"value3"}")发生的事情是 JSON 对象中的“,”被视为字段分隔符,并且 JSON 被分解为数组节点。除了编写脚本来检测以“{ 和 } 结尾的字段”之外,我如何将整个 json 字符串作为一个字段读取(因为它在数据库中)?或者,也许有更好的方法来输出字符串,以便可以将其作为一个项目读取?
查看完整描述

2 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

如果不是仅仅使用像file_put_contents()你这样的东西写出数据,而是使用一些为 CSV 文件设计的方法,这将为你完成大部分工作......


要写入数据使用fputcsv(),这会转义分隔符(在这种情况下,“变为”)...


$row = ["894","Somebody","Related","2020-02-20",'{"name1":"value1","name2":"value2","name3":"value3"}',"expired"];


$fh = fopen($filepath, "a");

fputcsv($fh, $row);

fclose($fh);

这将写入文件


894,Somebody,Related,2020-02-20,"{""name1"":""value1"",""name2"":""value2"",""name3"":""value3""}",expired

然后从文件中读取,一次只读一行并使用fgetcsv()...


$fh = fopen($filepath, "r");

print_r(fgetcsv($fh));   // This in a loop to read all lines

fclose($fh);

这表明


Array

(

    [0] => 894

    [1] => Somebody

    [2] => Related

    [3] => 2020-02-20

    [4] => {"name1":"value1","name2":"value2","name3":"value3"}

    [5] => expired

)


查看完整回答
反对 回复 2023-04-15
?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

解决此问题的一种方法是创建数组的新副本并操作新数组并将 json 添加为原始数组的切片部分。


$allRows = array_map('str_getcsv',file($fp)); 


$new_arr = [];

foreach($allRows[0] as $key=>$item) {


    $json = false;


    if (substr($item,0,1) == '{') {

        $json_start = $key;

        $json = true;

    }


    if (substr($item,-2,2) == '}"') {

        $json_stop = $key;

        $json = true;


        //Slice json-part from original array (in your case 4,5,6)

        $sl = array_slice($allRows[0], $json_start, ($json_stop-$json_start)+1);


        //Add the sliced part into key where json started

        $new_arr[$json_start] = implode('',$sl);         

    }


    if ($json === false) $new_arr[] = $item;

}

然后你在$new_arr.


查看完整回答
反对 回复 2023-04-15
  • 2 回答
  • 0 关注
  • 131 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信