我正在寻找一种简单的解决方法,将现有的嵌套JSON数据导入到几个MySQL表中。 JSON没有双向关系,因此我认为它们应该自动生成。
以下是数据样本:
[
{
"targetgroup": "Staff",
"plan": "this field just exists and should be ignored in database",
"budgetlevel": "Government",
"spots": 5,
"edutype": "Bachelor",
"qualilevel": "Specialist",
"speciality": "Mathematician",
"qualification": "Finished",
"faculty": "Applied mathematics",
"institute": "this field is sometimes empty in input data",
"eduform": "Full-time",
"profiles": [
"Jr. Arithmetic manager"
],
"entrancetests": [
{
"subject": "math",
"typeoftest": "GOV",
"minscore": "37",
"ratingtype": "out of 100"
},
{
"subject": "language",
"typeoftest": "GOV",
"minscore": "27",
"ratingtype": "out of 100"
},
{
"subject": "physics",
"typeoftest": "GOV",
"minscore": "40",
"ratingtype": "out of 100"
}
]
},
{
"targetgroup": "Educational workers",
"plan": "fridge",
"budgetlevel": "Legacy",
"spots": 26,
"edutype": "Bachelor",
"qualilevel": "Master",
"speciality": "Data analysis",
"qualification": "Finished",
"faculty": "Machine learning mathematics",
"institute": "",
"eduform": "Full-time",
"profiles": [
"Head counting manager"
],
"entrancetests": [
{
"subject": "Discrete mathematics",
"typeoftest": "GOV",
"minscore": "32",
"ratingtype": "Out of 100"
},
{
"subject": "Algorythm theory",
"typeoftest": "GOV",
"minscore": "51",
"ratingtype": "Out of 100"
},
{
"subject": "Advanced exception catching",
"typeoftest": "GOV",
"minscore": "56",
"ratingtype": "Out of 100"
}
]
}
]
数据库结构:
表格“dep:”
id(自动增量)| targetgroup | budgetlevel |斑点| edutype ...等,与JSON字段名称相同
表格“个人资料”
id(相对于相应的父块)|名称
表“参加考试”:
id(相对于相应的父块)|主题| typeoftest | minscore | RATINGTYPE
我对如何导入非嵌套JSON有一个大概的想法,但我很难搞清楚如何添加关系,如何在循环中定义父块?提前谢谢。
答案 0 :(得分:2)
$json='[
{
"targetgroup": "Staff",
"plan": "this field just exists and should be ignored in database",
"budgetlevel": "Government",
"spots": 5,
"edutype": "Bachelor",
"qualilevel": "Specialist",
"speciality": "Mathematician",
"qualification": "Finished",
"faculty": "Applied mathematics",
"institute": "this field is sometimes empty in input data",
"eduform": "Full-time",
"profiles": [
"Jr. Arithmetic manager"
],
"entrancetests": [
{
"subject": "math",
"typeoftest": "GOV",
"minscore": "37",
"ratingtype": "out of 100"
},
{
"subject": "language",
"typeoftest": "GOV",
"minscore": "27",
"ratingtype": "out of 100"
},
{
"subject": "physics",
"typeoftest": "GOV",
"minscore": "40",
"ratingtype": "out of 100"
}
]
},
{
"targetgroup": "Educational workers",
"plan": "fridge",
"budgetlevel": "Legacy",
"spots": 26,
"edutype": "Bachelor",
"qualilevel": "Master",
"speciality": "Data analysis",
"qualification": "Finished",
"faculty": "Machine learning mathematics",
"institute": "",
"eduform": "Full-time",
"profiles": [
"Head counting manager"
],
"entrancetests": [
{
"subject": "Discrete mathematics",
"typeoftest": "GOV",
"minscore": "32",
"ratingtype": "Out of 100"
},
{
"subject": "Algorythm theory",
"typeoftest": "GOV",
"minscore": "51",
"ratingtype": "Out of 100"
},
{
"subject": "Advanced exception catching",
"typeoftest": "GOV",
"minscore": "56",
"ratingtype": "Out of 100"
}
]
}
]';
$db=new PDO("mysql:host=yourhost;dbname=yourdbname;charset=utf8","username","password");
try{
$db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); // this will deny subsequent queries from being executed if there is an error and permit exception handle at the bottom
$db->beginTransaction();
// dep
$dep_cols=array("targetgroup","budgetlevel","spots",
"edutype","qualilevel","speciality","qualification",
"faculty","institute","eduform"); // declare columns
$dep_keys=array_map(function($v){return ":$v";},$dep_cols); // build :keys
$dep_cols=array_combine($dep_keys,$dep_cols); // assign :keys
var_export($dep_cols);
$dep_query="INSERT INTO `dep` (`".implode('`,`',$dep_cols)."`)"; // list columns as csv
$dep_query.=" VALUES (".implode(',',array_keys($dep_cols)).");";
echo "<div>$dep_query</div>";
$stmt_add_dep=$db->prepare($dep_query);
// profile
$profile_cols=array('name');
$profile_query="INSERT INTO `profile` (`id`,`".implode('`,`',$profile_cols)."`)"; // list columns as csv
$profile_query.=" VALUES (LAST_INSERT_ID(),".implode(',',array_fill(0,sizeof($profile_cols),"?")).");";
echo "<div>$profile_query</div>";
// entrancetests
$entrance_cols=array('subject','typeoftest','minscore','ratingtype'); // declare columns
$entrance_keys=array_map(function($v){return ":$v";},$entrance_cols); // build :keys
$entrance_cols=array_combine($entrance_keys,$entrance_cols); // assign :keys
var_export($entrance_cols);
$entrance_query="INSERT INTO `entrancetests` (`id`,`".implode('`,`',$entrance_cols)."`)"; // list columns as csv
$entrance_query.=" VALUES (LAST_INSERT_ID(),".implode(',',array_keys($entrance_cols)).");";
echo "<div>$entrance_query</div>";
$stmt_add_entrance=$db->prepare($entrance_query);
foreach(json_decode($json) as $d){
foreach($dep_cols as $k=>$v){
$stmt_add_dep->bindValue($k,(property_exists($d,$v)?$d->$v:""));
echo "<div>$k => {$d->$v}</div>";
}
$stmt_add_dep->execute();
echo "<div>Dep Affected Rows: ",$stmt_add_dep->rowCount(),"</div><br>";
$stmt_add_profile=$db->prepare($profile_query);
foreach($d->profiles as $k=>$v){
$stmt_add_profile->bindValue($k+1,$v);
echo "<div>",$k+1," => $v</div>";
}
$stmt_add_profile->execute();
echo "<div>Profile Affected Rows: ",$stmt_add_profile->rowCount(),"</div><br>";
foreach($d->entrancetests as $o){
foreach($entrance_cols as $k=>$v){
$stmt_add_entrance->bindValue($k,(property_exists($o,$v)?$o->$v:""));
echo "<div>$k => {$o->$v}</div>";
}
}
$stmt_add_entrance->execute();
echo "<div>Entrance Affected Rows: ",$stmt_add_entrance->rowCount(),"</div><br>";
}
// $db->commit(); // Only use with InnoDB tables. MyISAM is auto-commit
}
catch(PDOException $e){
// $db->rollBack(); // Only works if InnoDB table. If MyISAM table, it doesn't rollback.
echo "Error message: {$e->getMessage()}. File: {$e->getFile()}. Line: {$e->getLine()}";
// do not show these error messages to users when you go live
}
按原样,如果查询有错误,此脚本将停止执行后续查询。
我知道有很多SO用户具有pdo流程方面的专业知识。如果有人发现任何问题或有可以改进我的代码的建议,请遏制向我投降的冲动;而只是给我一个建设性的评论,具体解释什么是不对的/好的,可能还有如何解决它。记住,SO的目的是帮助人们,而不是通过让别人失望来提升自己。我总是愿意编辑我的答案,以便未来的SO读者可以访问最好的代码。