JSONからSQLを生成する — 型推論とINSERT文の自動化
APIレスポンスやCSVから変換したJSONデータをデータベースに投入したい場面は多くあります。手動でCREATE TABLEとINSERT文を書くのは手間がかかりますが、このツールを使えばJSONを貼るだけで自動生成できます。
型推論の仕組み
各カラムの値を全行スキャンしてSQL型を決定します。すべての値が整数なら INTEGER、浮動小数点数があれば REAL、文字列があれば TEXT、true/falseのみなら BOOLEAN として推論します。型が混在する場合は最も広い型(TEXT)が選ばれます。null値を含む行があるカラムはNULL許容(NOT NULL なし)になります。日付・時刻のISO 8601文字列(2024-01-15など)はデータベースによってTIMESTAMP型を推論することもあります。カラム名にidやIdが含まれる場合は自動でPRIMARY KEY候補として扱うことがあります。生成後のCREATE TABLE文はそのままSQLクライアントに貼り付けて実行できます。
方言ごとの違い
PostgreSQLとSQLiteはダブルクォートでカラム名・テーブル名を囲みますが、MySQLはバッククォートを使います。BOOLEAN型はPostgreSQL/SQLiteではTRUE/FALSEリテラルを使いますが、MySQLはTINYINT(1)で0/1で格納します。浮動小数点数はMySQLではDOUBLEが一般的なので自動的に変換されます。自動採番のPRIMARY KEYはPostgreSQLではSERIALまたはGENERATED ALWAYS AS IDENTITY、MySQLではAUTO_INCREMENT、SQLiteではINTEGER PRIMARY KEY(rowid のエイリアス)でそれぞれ定義方法が異なります。文字列の最大長もPostgreSQL/MySQLではVARCHAR(255)など指定しますが、SQLiteは長さ制限がなくTEXTのみで事足ります。
スキーマ名の活用
PostgreSQLでは`public.users`のようにスキーマ名を指定してテーブルを整理します。スキーマ名フィールドを入力すると`"schema"."table"`形式でCREATE TABLEとINSERT文が生成されます。MySQLの場合はデータベース名を指定することで`database`.`table`形式になります。PostgreSQLのスキーマはデータベース内の名前空間で、テナント分離(テナントごとにスキーマを切り替える)やモジュール分割(auth・billing・notificationなど)に活用されます。search_pathを設定すれば毎回スキーマ名を書かずにアクセスできます。SQLiteにはスキーマ概念がなく、ATTACHコマンドで複数データベースを接続する方法で代替します。
大量データの投入
生成されたINSERT文は全行を1つのINSERT INTO ... VALUES(...),(...),(...)形式(マルチロウINSERT)ではなく、行ごとに分けています。これにより1行ずつ実行して部分的にデバッグしやすくなります。大量データの本番投入にはPostgreSQLの\COPYやMySQLのLOAD DATA INFILEがCSVを直接読み込めるためより高速です。PostgreSQLではCOPY users FROM 'data.csv' CSV HEADERで数百万件のインポートも数秒で完了します。Node.jsではpg-copystreamsライブラリ、Pythonではpsycopgのcopy_expertメソッドを使って大量データをストリーミングINSERTできます。