web-dev-qa-db-ja.com

PostgreSQLエラー:リレーションは既に存在します

以前に削除されたテーブルを作成しようとしています。

しかし、CREATE TABLE A ..を実行すると。以下のエラーが発生しています:

リレーション 'A'は既に存在します。

SELECT * FROM Aの実行を確認しましたが、別のエラーが発生しました:

関係 'A'は存在しません。

すべての関係をリストする\dS+ですでに見つけようとしましたが、そこにはありません。
これを複雑にするために、別のデータベースにこのテーブルを作成してテストしましたが、同じエラーが発生しました。このテーブルが削除されたときにエラーになる可能性があると考えています。何か案は?

コードは次のとおりです。PowerSQLから生成されたコードを使用しています。シーケンスを使用せずに同じエラーが発生します。名前を変更しても機能しますが、この場合はできません。

CREATE SEQUENCE csd_relationship_csd_relationship_id_seq;
CREATE TABLE csd_relationship (
    csd_relationship_id INTEGER NOT NULL DEFAULT nextval('csd_relationship_csd_relationship_id_seq'::regclass),  
    type_id INTEGER NOT NULL,
    object_id INTEGER NOT NULL,
    CONSTRAINT csd_relationship PRIMARY KEY (csd_relationship_id)
);
38
nsbm

私はついにエラーを発見しました。問題は、主キー制約名がテーブル名と等しいことです。 postgresがどのように制約を表すかはわかりませんが、テーブルがすでに宣言されているため、主キー制約の作成中に「関係が既に存在します」というエラーがトリガーされたと思います。しかし、このエラーのため、テーブルは最後に作成されませんでした。

32
nsbm

ここには一重引用符はありません 'A'。単一引用符は文字列リテラル用です:'some value'
どちらも二重引用符を使用して、「A」の大文字のスペルを保持します。

CREATE TABLE "A" ...

または、引用符をまったく使用しないでください。

CREATE TABLE A ...

と同じです

CREATE TABLE a ...

引用符で囲まれていない識別子PostgreSQLでは自動的に小文字に変換される であるためです。


より単純な構文を使用すると、インデックス名に関する問題を完全に回避できます。

CREATE TABLE csd_relationship (
    csd_relationship_id serial PRIMARY KEY,
    type_id integer NOT NULL,
    object_id integer NOT NULL
);

元のクエリと同じですが、名前の競合を自動的に回避するだけです。次の空き識別子を自動的に選択します。 マニュアルのシリアルタイプ の詳細。

12

クラスター内の既存のテーブルまたはビューと同じ名前のテーブルを作成することはできません。既存のテーブルを変更するには、 _ALTER TABLE_(link) を使用するか、現在テーブルにあるすべてのデータを削除し、目的のスキーマで空のテーブルを作成するには、_DROP TABLE_を発行してから_CREATE TABLE_。

作成しているシーケンスが原因である可能性があります。 PostgreSQLでは、シーケンスは特定の列セットを持つテーブルとして実装されます。シーケンスが既に定義されている場合は、おそらく作成をスキップする必要があります。残念ながら、_CREATE SEQUENCE_には、_IF NOT EXISTS_で使用可能な_CREATE TABLE_コンストラクトに相当するものはありません。その見た目では、とにかくスキーマを無条件に作成している可能性があるため、使用するのが妥当です

_DROP TABLE IF EXISTS csd_relationship;
DROP SEQUENCE IF EXISTS csd_relationship_csd_relationship_id_seq;
_

スキーマの残りの更新前。明らかでない場合は、これにより、_csd_relationship_テーブルのすべてのデータが削除されます(存在する場合)

私の場合、同じ名前のシーケンスがありました。

3

「関係が既に存在する」などのエラーが表示されるもう1つの理由は、DROPコマンドが正しく実行されなかった場合です。

これが発生する理由の1つは、最初に閉じる必要があるデータベースに接続されている他のセッションがある場合です。

2
isedwards

私の場合、バッチファイルを一時停止して少し上にスクロールするまで、それが唯一のエラーではありませんでした。私のDROPコマンドはDROPになっていたので、テーブルはそもそもドロップしていませんでした(したがって、リレーションは実際にまだ存在していました)。私が学んだは、バイトオーダーマーク(BOM)と呼ばれます。これをNotepad ++で開き、エンコードをBOMなしのUTM-8に設定してSQLファイルを再保存すると、正常に実行されます。

2
user5775085

私の場合、9.5から9.6に移行していました。だから、データベースを復元するために、私はやっていた:

Sudo -u postgres psql -d databse -f dump.sql

もちろん、データがある古いpostgreSQLデータベースで実行されていました!新しいインスタンスがポート5433にある場合、正しい方法は次のとおりです。

Sudo -u postgres psql -d databse -f dump.sql -p 5433
0