確かにコマンドラインからの処理は必要ないですし、SQLを書かなくてもできてしまうことがたくさんあるので便利だとは思うんですが・・・。
特にデータのインポートはローカルファイルからインポートする形式のようなのですが、サーバにはDB以外にデータが残りませんし、文字コードの問題があり正常にインポートできない場合もあります。
だったら素直に事前に文字コード変換したテキストをFTPでサーバにアップしてそのファイルからDBへインポートしたいのです。
今回のはさくらインターネット上の処理なので色々と制限もあり尚更そう感じました。
なのでMYSQLへインポートするPHPファイルを作りました。
実際は
・テーブル作成(CREATE TABLE)
・データインポート(mysqlimport)
・データ削除(DELETE)
・テーブル削除(DROP)
をセットで作ったのですが、全部書くと長くなるのでインポート処理だけ書きます。
まずインポートですが、csvファイルなどをインポートする際よく使う、load data infile コマンドをphpMyAdmin上で実行したのですがうまく動いてくれません。
load data infile '/home/アカウント名/www/hoge/hogehoge.csv' into TABLE hogehoge FIELDS TERMINATED BY "," LINES TERMINATED BY '\r\n';
とすると、以下のエラーが出てしまいます。
#1045 - Access denied for user: 'アカウント名@%'
アップしたファイルに対しての権限はOKなはずなのでMYSQLを扱うユーザのDBに対する権限かなぁ。
いつもMYSQLを自分で入れるときはgrantで権限を与えてしまうのでこの辺りはあまり気にした事がなかったです。
これ、PHPでコマンド流してもエラーになるかな?と不安があったのですが、PHPからであれば成功しました。
ソースは以下のような感じにしました。
<?php
function db_con()
{
$connect = mysql_connect("与えられたサーバ名","アカウント名","パスワード");
if($connect == false)
{
echo "DBに接続できませんでした";exit;
}
mysql_select_db("DB名(アカウント名と同じ)");
}
//データ存在確認
function checkExistData($tablename)
{
$sql_exist = "select * from " . $tablename . ";";
$rs_exist = mysql_query($sql_exist);
$num = mysql_num_rows($rs_exist);
return $num;
}
db_con();
$csvname = "hogehoge.csv";
//テーブル名
$tablename = substr($csvname,0,-4);
//既にデータがあるか確認、なければインポート
$numrows = checkExistData($tablename);
//データが入っている場合
if($numrows > 0)
{
$mess = $tablename . " には既にデータが入っています。インポートする場合はデータを削除してから実行してください。";
}
else
{
//インポート文作成
$strimport = 'mysqlimport --fields-terminated-by="," -L --host=サーバ名 --user=アカウント名 --password=パスワード DB名 /home/アカウント名/www/hogehoge/' . $csvname;
echo $strimport."<br>";
//インポート
system($strimport);
echo "<br><br>";
$mess = $tablename . " に" . $csvname . " のデータをインポートしました。";
}
?>
・PHPファイルの初期画面は、アップ済みのcsvファイルの一覧がラジオボタンと一緒に表示されていて、どれかを選択してインポートボタンを押すとテーブルにデータがインポートされるというものにしています。
ですので
$csvname = "hogehoge.csv";
は、実際はPOSTなりGETなりで渡されたcsv名を$csvnameに格納して使うという形になります。
・インポート先テーブルに既にデータが存在する場合にインポートを実行すると、テーブル定義次第では二重に入ってしまう可能性があるのでその場合は一度データ削除を促してからインポートするようにしています。
・functionは他の場所で何回か使っているので関数にしてあるだけです。
・mysqlimportコマンドはhogehoge.csvのインポート先はhogehogeという名前のテーブルになります。なのでcsv名とインポート先のテーブル名は同じになるようにしておきます。
・$messはhtml内のどこにでもechoしてください(笑)
ざっとこんな感じになります。
テーブル作成、インポート、データ削除、テーブル削除を作ってしまえばphpMyAdminですることは入っているデータの確認くらい(それも作ってしまいましたが。。)ですかね。
細かい作業はSSHで
mysql -hサーバ名 -uアカウント名 -pパスワード
と打ってログインして操作する方が慣れているので今後もこれでいけばいいかなと。
しかし、さくらインターネットで契約している方はphpMyAdminでうまくMYSQLを使いこなせているのでしょうか。。
逆にそれくらいできるようにならないとまずいのかなぁともちょっと思いました。。
(条件によってはphpMyAdminしか使わせてもらえないクライアントもありそうですしね・・・)
追記:
私がよくお邪魔させていただいている創るmetaboyさんの記事で、
創るmetaboy load data infile で、Access denied for user'hogehoge'@'localhost'(using password:YES) ・・・ 【MySQL】
という記事がありました。
この記事ではlocalオプションをつけたらインポートできたと書かれているのですが、
localオプションの説明を見ると
「FILE権限なしで、ローカルファイルの読み込みが可能になります。」
だそうなのでローカルファイルをサーバにインポートする場合のコマンドですよね。
だとすれば、やっぱりサーバにアップしたデータをphpMyAdmin上でload data infileするのは無理なんでしょうかねぇ・・・。
上記続き。
echo $csvname . "としてアップロードしました。<br>MySQLに取り込みます。<br>";
$filepath= str_replace("\\","/", realpath( "." )."/csv/".$csvname );
$sql="LOAD DATA LOCAL INFILE '".$filepath."' INTO TABLE MDB_IMPORT FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\r\n';";
$result = mysql_query($sql);
というか、system関数ではエラーが見づらいので、MySQLのQueryで実行しました。