mysql:16571
From: yoku0825 <yoku0825 <yoku0825@xxxxxxxxxx>>
Date: Wed, 11 Mar 2020 14:04:59 +0900
Subject: [mysql 16571] Re: [mysql 16570] Re: [mysql 16567] LOAD DATA INFILEでdefault値がないというエラー(Field 'SHAPE' doesn't have a default value)
yoku0825といいます。 いただいたデータで試してみましたが、8.0.12ではおっしゃる通りのエラーに、 8.0.19ではエラーにならず正しく格納されました。 (LOAD DATA LOCAL INFILEでも蹴られるんですね) というわけで取り急ぎ「最新版でお試しください」みたいな感じになりました。 yoku0825, 2020年3月11日(水) 11:46 落合 司郎 <s.ochiai@xxxxxxxxxx>: > > yoku0825さま > > いつもお世話になります。 > > インプットのCSVファイルは、統計局の「地図で見る統計(統計GIS)データダウンロード」サイトでダウンロードした平成28年経済センサス-活動調査−世界測地系平面直角座標系(500mメッシュ)のshapeファイルをGDAL > 2.4.2に含まれていたogr2ogr.exeでCSVファイルに変換したものです。 > https://www.e-stat.go.jp/gis/statmap-search?page=6&type=2&aggregateUnitForBoundary=Q&coordsys=2&format=shape > > (SHAPE to CSV) > ogr2ogr.exe -f CSV C:...\MESH05439.csv C:...\MESH05439.shp -lco > GEOMETRY=AS_WKT > > なお、ogr2ogr.exeでCSVファイルを直接MySQLのテーブルに取り込むことはできましたが、どうも、1行ごとにINSERTしているようなので、我慢できないほど時間がかかったので、MySQLのLOAD > DATA LOCAL INFILEで取り込むことにしました。 > (CSV to MySQL) > ogr2ogr.exe -f MySQL MySQL:..... C:...\QXYSWQ5439\MESH05439.csv > > なお、ogr2ogr.exeでshapeファイルを直接MySQLのテーブルに取り込むのは、CSVファイルとテーブル、カラムとのキャラクタセットの関係で取り込めない場合があるので、一旦CSVファイルに変換し、ファイルを確認し、MySQLに取り込む手順とした次第です。 > > サンプルデータとして、上記CSVファイルの前後の各10レコード、合計20レコードを抽出したファイルを送ります。 > > よろしくご確認願います。 > > ところで、ご教示いただいた > > `SHAPE` geometry NOT NULL DEFAULT (ST_GeometryFromText(wkt_tmp, > 2451)), > は構文エラーでテーブル定義できませんでした。 > Error Code: 1064. You have an error in your SQL syntax; check the manual > that corresponds to your MySQL server version for the right syntax to > use near '(ST_GeometryFromText(wkt_tmp, 2451)), PRIMARY KEY > `OGR_FID` (`OGR_FID`), ' at line 11 > 実行環境は、8.0.12(MySQL Community Server - GPL)です。 > > 下記マニュアルを確認したところ、Handling of Explicit Defaults as of MySQL > 8.0.13の項に > The default value specified in a DEFAULT clause can be a literal > constant or an expression. With one exception, enclose expression > default values within parentheses to distinguish them from literal > constant default values. > とありました。 > そこで、MySQL 8.0.13で試してみます。 > 結果は後日ご報告。 > https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html > > On 2020/03/08 12:07, yoku0825 wrote: > > yoku0825といいます。 > > > >> そこで、止む無く下記のようにGeometryフィールドをdefault NULLとし、SPATIAL > >> KEYも設定せずにテーブルを定義し、上記のLOAD DATA > >> INFILEを実行すると、エラーは発生しません。 > > > > この時、中身にはジオメトリ型のデータがちゃんと入っていそうですか? (NULLにはなっていない? > > > > NULLになってしまっているなら、渡すデータが何かしらおかしい気がしますし、 > > ちゃんとデータが入っているなら↓の通りになるんだと思います。 > > > >> LOAD DATA INFILEのSET構文でSpatial > >> Functionを使う場合にバグがあるのではないでしょうか? > > > > MySQLのユーザー定義変数(この場合は @wkt_tmp )にはデータ型がないので、 > > ST_GeometryFromTextが許容する以外のデータ型として一度格納されてしまっているんじゃないかなあと想像しています。 > > > > @wkt_tmpに入れている文字列を1つで良いのでサンプルとして出してもらえないでしょうか? > > (それで再現するならバグレポートもできるので) > > > > > > ところで本文中、 LOAD DATA INFILEとLOAD DATA LOCAL INFILEがちょこちょこ混じっていて、 > > LOAD DATA LOCAL INFILEの方は「常にエラーをIGNOREする」ような動きになる気がするのですが、 > > これはLOAD DATA INFILEの方でやった結果ですかね…? (でないと今度はドキュメント間違いの可能性が > > > >> With LOAD DATA LOCAL, data-interpretation and duplicate-key errors become warnings and the operation continues because the server has no way to stop transmission of the file in the middle of the operation. For duplicate-key errors, this is the same as if IGNORE is specified. IGNORE is explained further later in this section. > > > > https://dev.mysql.com/doc/refman/8.0/en/load-data.html > > > > > > このカラムが残っても良いなら、wkt_tmpそのものを一度カラムに格納させてしまって式デフォルトを使ってSHAPEカラムを派生させたりできないでしょうかね…。 > > (不要なら最後にwkt_tmpカラムをDROPしてしまう…この時式デフォルトもいじらないとエラーになりそうな予感がしてきましたが) > > > > CREATE TABLE `mesh05439` ( > > `OGR_FID` int(11) NOT NULL AUTO_INCREMENT, > > `wkt_tmp` text, > > `key_code` text, > > `mesh1_id` text, > > `mesh2_id` text, > > `mesh3_id` text, > > `mesh4_id` text, > > `mesh5_id` text, > > `obj_id` text, > > `SHAPE` geometry NOT NULL DEFAULT (ST_GeometryFromText(wkt_tmp, 2451)), > > PRIMARY KEY `OGR_FID` (`OGR_FID`), > > SPATIAL KEY `SHAPE` (`SHAPE`) > > ) ENGINE=InnoDB; > > > > 2020年3月4日(水) 11:49 落合 司郎 <s.ochiai@xxxxxxxxxx>: > >> > >> いつもお世話になります。 > >> > >> WKT形式で記述されたGeometryデータを含むCSVファイルをLOAD DATA > >> INFILEでテーブルに取り込もうとしています。 > >> Geometryデータを取り込むGeometryフィールドにはSPATIAL KEYを設定したいため、NOT > >> NULL制約をつける必要があり、取り込み先のテーブルを以下のようにGeometryフィールドをNOT > >> NULL、default値を設定しないで定義しました。 > >> > >> #エラーが発生したときのテーブル > >> # geometry型(NOT NULL)を含むテーブル定義 > >> drop tables if exists mesh05439; > >> CREATE TABLE `mesh05439` ( > >> `OGR_FID` int(11) NOT NULL AUTO_INCREMENT, > >> `SHAPE` geometry NOT NULL, > >> `key_code` text, > >> `mesh1_id` text, > >> `mesh2_id` text, > >> `mesh3_id` text, > >> `mesh4_id` text, > >> `mesh5_id` text, > >> `obj_id` text, > >> PRIMARY KEY `OGR_FID` (`OGR_FID`), > >> SPATIAL KEY `SHAPE` (`SHAPE`) > >> ) ENGINE=InnoDB; > >> > >> 下記に示すLOAD DATA > >> INFILEを実行すると、CSVファイルのすべてのレコードにデータに値があっても、default値がないというエラーが発生しました。 > >> なお、LOAD DATA > >> INFILEで取り込むCSVファイルはtextファイルでなければならないので、CSVファイルのGeometryデータはWKTフォーマットの文字列としています。 > >> LOAD DATA > >> INFILEではGeometryデータをワーク変数を割り当て、SET構文でST_GeometryFromText()でGeometryフィールドに値をセットしています。 > >> > >> #実行したLOAD DATA INFILE > >> # LOAD DATA > >> INFILEで取り込むCSVファイルはtextファイルでなければならないので、 > >> # CSVファイルではGeometryデータはWKTフォーマットの文字列とし、LOAD DATA > >> INFILEではワーク変数を割り当て、 > >> # SET構文でST_GeometryFromText()でGeometryフィールドに値をセットします。 > >> > >> LOAD DATA LOCAL INFILE 'C:******/MESH05439.csv' INTO TABLE mesh05439 > >> FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\r\n' > >> IGNORE 1 LINES > >> (@wkt_tmp, key_code, mesh1_id, mesh2_id, mesh3_id, mesh4_id, mesh5_id, > >> obj_id) SET SHAPE=ST_GeometryFromText(@wkt_tmp,2451); > >> > >> # 発生したエラー > >> Error Code: 1364. Field 'SHAPE' doesn't have a default value > >> > >> > >> そこで、止む無く下記のようにGeometryフィールドをdefault NULLとし、SPATIAL > >> KEYも設定せずにテーブルを定義し、上記のLOAD DATA > >> INFILEを実行すると、エラーは発生しません。 > >> > >> drop tables if exists mesh05439; > >> CREATE TABLE `mesh05439` ( > >> `OGR_FID` int(11) NOT NULL AUTO_INCREMENT, > >> `SHAPE` geometry default NULL, > >> `key_code` text, > >> `mesh1_id` text, > >> `mesh2_id` text, > >> `mesh3_id` text, > >> `mesh4_id` text, > >> `mesh5_id` text, > >> `obj_id` text, > >> PRIMARY KEY `OGR_FID` (`OGR_FID`) > >> ) ENGINE=InnoDB; > >> > >> GeometryフィールドにはSPATIAL KEYを設定したいので、取り込んだ後に、ALTER TABLEでGeometryフィールドをNOT > >> NULLに、また、SPATIAL KEYを追加する手順としています。 > >> > >> ALTER TABLE `mesh05439` > >> CHANGE COLUMN `SHAPE` `SHAPE` GEOMETRY NOT NULL , > >> ADD SPATIAL KEY `SHAPE` (`SHAPE`); > >> > >> > >> ところで、LOAD DATA INFILEでワーク変数を割り当て、SET構文でテーブルのNOT > >> NULLで定義されたフィールドに値を設定することは、Geometry型以外のフィールドならばSpatial > >> Functionを含まない計算式なら問題なくできます。 > >> > >> LOAD DATA INFILEのSET構文でSpatial > >> Functionを使う場合にバグがあるのではないでしょうか? > >> > >> 実行環境: > >> OS:Windows 8.0 64ビット > >> MySQL:Ver.8.0.12 GPL版 > >> Workbench:Ver.6.3.9 > >>