Par exemple, vous avez une donnée en base, et pour vos tests, vous en voudriez 10 000.
Il est possible d’utiliser cette boucle SQL pour faire 10 000 insertions :
-- Copie d’une ligne n fois
--
-- Paramètres modifiables :
-- - nb de fois (ici 10000)
-- - table concernée (ici my_table)
-- - liste des colonnes à copier (ici column_1, column_2, column_x)
-- - id de la ligne à copier (ici 1)
DO
$$
DECLARE
i integer;
BEGIN
FOR i IN 1..10000
LOOP
INSERT INTO public.my_table (column_1, column_2, column_x)
SELECT column_1, column_2, column_x
FROM public.my_table
WHERE id = 1;
END LOOP;
END
$$ LANGUAGE plpgsql;
Pour générer cette requête avec toutes les colonnes de votre table, vous pouvez faire générer l’INSERT directement à
PostgreSQL, avec la requête suivante :
-- Génération de la requête d’insertion avec toutes les colonnes sauf la colonne id (car auto-incrémentale)
--
-- Paramètres modifiables :
-- - table concernée (ici my_table)
-- - id de la ligne à copier (ici 1)
WITH cols AS (SELECT column_name, ordinal_position
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'my_table'
AND column_name NOT IN ('id')
ORDER BY ordinal_position)
SELECT format(
'INSERT INTO %I.%I (%s) SELECT %s FROM %I.%I WHERE id = 1;',
'public',
'my_table', string_agg(quote_ident(column_name), ', '), string_agg(quote_ident(column_name), ', '),
'public', 'my_table') AS sql
Un dernier problème se pose si certaines colonnes doivent contenir des données uniques.
Dans les INSERT précédents, on ne gère que le cas de la colonne id, supposée auto-incrémentale. Pour générer des
données pour d’autres colonnes, remplacez la requête précédente par celle-ci :
-- Génération de la requête de copie avec toutes les colonnes sauf celle contenant des ID uniques
--
-- Paramètres modifiables :
-- - table concernée (ici my_table)
-- - liste des colonnes pour lesquelles générer des uuid uniques (ici 'uuid1', 'uuid2')
-- - id de la ligne à copier (ici 1)
WITH cols AS (SELECT column_name, ordinal_position
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'my_table'
AND column_name NOT IN ('id', 'uuid1', 'uuid2')
ORDER BY ordinal_position)
SELECT format(
'INSERT INTO %I.%I (uuid1, uuid2, %s) SELECT gen_random_uuid(), gen_random_uuid(), %s FROM %I.%I WHERE id = 1;',
'public',
'my_table', string_agg(quote_ident(column_name), ', '), string_agg(quote_ident(column_name), ', '),
'public', 'my_table') AS sql
Note : si les valeurs uniques ne sont pas des UUID, il faut rechercher si PostgreSQL propose d’autres fonctions de
génération aléatoires que gen_random_uuid().