web-dev-qa-db-ja.com

Postgresデータベースのすべてのテーブルを切り捨てる

再構築する前に、PostgreSQLデータベースからすべてのデータを定期的に削除する必要があります。これをSQLで直接行うにはどうすればよいですか?

現時点では、実行する必要があるすべてのコマンドを返すSQLステートメントを作成することができました。

SELECT 'TRUNCATE TABLE ' ||  tablename || ';' FROM pg_tables WHERE tableowner='MYUSER';

しかし、それらを一度プログラムで実行する方法はわかりません。

137
Sig

FrustratedWithFormsDesignerは正しいです、PL/pgSQLはこれを行うことができます。スクリプトは次のとおりです。

CREATE OR REPLACE FUNCTION truncate_tables(username IN VARCHAR) RETURNS void AS $$
DECLARE
    statements CURSOR FOR
        SELECT tablename FROM pg_tables
        WHERE tableowner = username AND schemaname = 'public';
BEGIN
    FOR stmt IN statements LOOP
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(stmt.tablename) || ' CASCADE;';
    END LOOP;
END;
$$ LANGUAGE plpgsql;

これにより、後から次のように使用できるストアド関数が作成されます(これは一度だけ行う必要があります)。

SELECT truncate_tables('MYUSER');
198
Henning

Plpgsqlでは、明示的なカーソルはほとんど必要ありません。 FOR ループのよりシンプルで高速な暗黙カーソルを使用します。

注:テーブル名はデータベースごとに一意ではないため、テーブル名をスキーマで修飾して確認する必要があります。また、関数をデフォルトのスキーマ「public」に制限します。ニーズに適応しますが、システムスキーマpg_*およびinformation_schemaを必ず除外してください。

非常に慎重これらの関数を使用してください。彼らはあなたのデータベースを破壊します。子供の安全装置を追加しました。 RAISE NOTICE行にコメントを付け、EXECUTEのコメントを外して爆弾を準備します...

CREATE OR REPLACE FUNCTION f_truncate_tables(_username text)
  RETURNS void AS
$func$
DECLARE
   _tbl text;
   _sch text;
BEGIN
   FOR _sch, _tbl IN 
      SELECT schemaname, tablename
      FROM   pg_tables
      WHERE  tableowner = _username
      AND    schemaname = 'public'
   LOOP
      RAISE NOTICE '%',
      -- EXECUTE  -- dangerous, test before you execute!
         format('TRUNCATE TABLE %I.%I CASCADE', _sch, _tbl);
   END LOOP;
END
$func$ LANGUAGE plpgsql;

format() にはPostgres 9.1以降が必要です。古いバージョンでは、クエリ文字列を次のように連結します。

'TRUNCATE TABLE ' || quote_ident(_sch) || '.' || quote_ident(_tbl)  || ' CASCADE';

単一コマンド、ループなし

TRUNCATE 一度に複数のテーブルを作成できるため、カーソルやループはまったく必要ありません。

すべてのテーブル名を集約し、単一のステートメントを実行します。よりシンプルで高速:

CREATE OR REPLACE FUNCTION f_truncate_tables(_username text)
  RETURNS void AS
$func$
BEGIN
   RAISE NOTICE '%', 
   -- EXECUTE  -- dangerous, test before you execute!
  (SELECT 'TRUNCATE TABLE '
       || string_agg(format('%I.%I', schemaname, tablename), ', ')
       || ' CASCADE'
   FROM   pg_tables
   WHERE  tableowner = _username
   AND    schemaname = 'public'
   );
END
$func$ LANGUAGE plpgsql;

コール:

SELECT truncate_tables('postgres');

洗練されたクエリ

関数も必要ありません。 Postgres 9.0以降では、 DO ステートメントで動的コマンドを実行できます。また、Postgres 9.5以降では、構文はさらにシンプルになります。

DO
$func$
BEGIN
   RAISE NOTICE '%', 
   -- EXECUTE
   (SELECT 'TRUNCATE TABLE ' || string_agg(oid::regclass::text, ', ') || ' CASCADE'
    FROM   pg_class
    WHERE  relkind = 'r'  -- only tables
    AND    relnamespace = 'public'::regnamespace
   );
END
$func$;

pg_classpg_tablesinformation_schema.tablesの違いについて:

regclassと引用符で囲まれたテーブル名について:

繰り返し使用する場合

Vanilla構造とすべての空のテーブルで"template"データベース(名前をmy_templateにしましょう)を作成します。次に、DROP/ CREATE DATABASEサイクルを実行します。

DROP DATABASE mydb;
CREATE DATABASE mydb TEMPLATE my_template;

Postgresはファイルレベルで構造全体をコピーするため、これはextremelyfastです。並行性の問題やその他のオーバーヘッドが原因で速度が低下することはありません。

同時接続によってDBが削除されない場合は、次のことを考慮してください。

82

これを行う必要がある場合は、現在のデータベースのスキーマsqlを作成し、dbをドロップして作成し、dbをスキーマsqlでロードします。

含まれる手順は次のとおりです。

1)データベースのスキーマダンプを作成(--schema-only

pg_dump mydb -s > schema.sql

2)データベースの削除

drop database mydb;

3)データベースの作成

create database mydb;

4)スキーマのインポート

psql mydb < schema.sql

33
Sandip Ransing

この場合、空のデータベースをテンプレートとして使用し、更新する必要がある場合は、既存のデータベースを削除して、テンプレートから新しいデータベースを作成することをお勧めします。

9
Scott Bailey

AUTO_INCREMENTバージョンのクリーニング:

CREATE OR REPLACE FUNCTION truncate_tables(username IN VARCHAR) RETURNS void AS $$
DECLARE
    statements CURSOR FOR
        SELECT tablename FROM pg_tables
        WHERE tableowner = username AND schemaname = 'public';
BEGIN
    FOR stmt IN statements LOOP
        EXECUTE 'TRUNCATE TABLE ' || quote_ident(stmt.tablename) || ' CASCADE;';

        IF EXISTS (
            SELECT column_name 
            FROM information_schema.columns 
            WHERE table_name=quote_ident(stmt.tablename) and column_name='id'
        ) THEN
           EXECUTE 'ALTER SEQUENCE ' || quote_ident(stmt.tablename) || '_id_seq RESTART WITH 1';
        END IF;

    END LOOP;
END;
$$ LANGUAGE plpgsql;
3
RomanGorbatko

動的SQLを使用して、各ステートメントを順番に実行できますか?これを行うには、おそらくPL/pgSQLスクリプトを作成する必要があります。

http://www.postgresql.org/docs/8.3/static/plpgsql-statements.html (セクション38.5.4。動的コマンドの実行)

これは、bashでも実行できます。

#!/bin/bash
PGPASSWORD='' psql -h 127.0.0.1 -Upostgres sng --tuples-only --command "SELECT 'TRUNCATE TABLE ' || schemaname || '.' ||  tablename || ';' FROM pg_tables WHERE schemaname in ('cms_test', 'ids_test', 'logs_test', 'sps_test');" | 
tr "\\n" " " | 
xargs -I{} psql -h 127.0.0.1 -Upostgres sng --command "{}"

スキーマに一致するように、スキーマ名、パスワード、およびユーザー名を調整する必要があります。

3
simao

みんなより良くてきれいな方法は:

1)データベースのスキーマダンプを作成します(-スキーマのみ)pg_dump mydb -s> schema.sql

2)データベースの削除データベースmydbの削除。

3)データベースの作成データベースmydbの作成。

4)スキーマpsql mydb <schema.sqlのインポート

それは私のために働いています!

ごきげんよう。ハイラムウォーカー

2
Hiram Walker

pgAdmin でデータを削除し、テーブル構造を保持するには、次のようにします。

  • データベースを右クリック->バックアップ、「スキーマのみ」を選択
  • データベースを削除する
  • 新しいデータベースを作成し、以前のような名前を付けます
  • 新しいデータベースを右クリック->復元->バックアップを選択し、「スキーマのみ」を選択
2
mYnDstrEAm