ちょっとした技術メモを忘れないうちに書いていく

PostgreSQL generate_seriesを使って大量にテストデータを作成する

2021-05-13

テスト生成ツールを使わずにササっとテストデータを作成する


generate_seriesとは

引数に開始値、終了値、刻み値を指定し、その範囲の値を返す集合関数。

-- 2~5を順番に返す
SELECT * FROM generate_series(2,5);
 generate_series
-----------------
               2
               3
               4
               5
(4)

--第3引数に刻む数値を指定する
--1~10までで2ずつ加算した結果を返す
SELECT * FROM generate_series(1,10,2);
 generate_series
-----------------
               1
               3
               5
               7
               9
(5)


--大きい値から減算もできる
SELECT * FROM generate_series(20, -10, -7);
 generate_series
-----------------
              20
              13
               6
              -1
              -8
(5)

--少数点もいけちゃう
SELECT * FROM generate_series(1.1 , 1.5, 0.08);
 generate_series
-----------------
             1.1
            1.18
            1.26
            1.34
            1.42
            1.50
(6)


--日付、時刻の加算も可能
SELECT * FROM generate_series('2021-05-01'::date, '2021-07-20' ,'7 day');
    generate_series
------------------------
 2021-05-01 00:00:00+09
 2021-05-08 00:00:00+09
 2021-05-15 00:00:00+09
 2021-05-22 00:00:00+09
 2021-05-29 00:00:00+09
 2021-06-05 00:00:00+09
 2021-06-12 00:00:00+09
 2021-06-19 00:00:00+09
 2021-06-26 00:00:00+09
 2021-07-03 00:00:00+09
 2021-07-10 00:00:00+09
 2021-07-17 00:00:00+09
(12)

テスト用テーブルを作成

とりあえずテストデータを登録するテーブルを作成。

--テーブル作成
CREATE TABLE test_data
(
    id integer NOT NULL, 
    name text , 
    type integer,
    delete_flg boolean,
    last_update timestamp without time zone,
	CONSTRAINT test_data_pkey PRIMARY KEY (id)
)

generate_seriesを使ったINSERT

以下のようなデータを作成したいとする

  • id:連番を登録
  • name:連番が付与された文字列
  • type:0~4までのランダムな値を設定

基本はSELECTで取得した値をINSERTする形式。 generate_seriesにAS句でエイリアスをつけるとSELECT内から「i」で参照できる。

INSERT INTO test_data(id, name,type, delete_flg, last_update)
SELECT
  i, -- 生成されたiをidに指定
  format('テスト%s', i), --文字列に連番として付与する
  (SELECT (random() * 10000)::INTEGER % 5  + i - i),--0~4のランダムな値を設定
  false,
  clock_timestamp()
FROM
  generate_series(1, 300000) AS i
;

typeに設定するランダムな値は「(SELECT (random() * 10000)::integer % 5)」だけだと、同じ値になってしまったので、毎回評価されるように「 + i - i」を追加している。

ちゃんと登録できているか確認。

SELECT COUNT(0) FROM test_data;
 count
--------
 300000
(1)


SELECT * FROM test_data ORDER BY id;
   id   |     name     | type | delete_flg |        last_update
--------+--------------+------+------------+----------------------------
      1 | テスト1      |    4 | f          | 2021-05-14 15:43:00.430394
      2 | テスト2      |    0 | f          | 2021-05-14 15:43:00.431145
      3 | テスト3      |    1 | f          | 2021-05-14 15:43:00.431172
-- 省略
 299999 | テスト299999 |    4 | f          | 2021-05-14 15:43:02.893391 
 300000 | テスト300000 |    2 | f          | 2021-05-14 15:43:02.893399

目次