4

バックグラウンド:

私が現在開発しているアプリケーションは、SQLite3 から PostgreSQL に移行中です。.dump現在のデータベースから を使用して、タイプのすべてのテーブルを変更して、すべてのデータが正常に移行されました

CREATE TABLE foo (
    id INTEGER NOT NULL, 
    bar INTEGER,
    ...
    PRIMARY KEY (id),
    FOREIGN KEY(bar) REFERENCES foobar (id),
    ...
);

CREATE TABLE foo (
    id SERIAL NOT NULL, 
    bar INTEGER,
    ...
    PRIMARY KEY (id),
    FOREIGN KEY(bar) REFERENCES foobar (id) DEFERRABLE,
    ...
);

SET CONSTRAINTS ALL DEFERRED;

私はSQLAlchemyを使用しているので、それ以降はスムーズに動作することを期待していました.もちろんengine. しかし、問題は、主キーの一意の値への自動インクリメントにあるようINSERTです。

たとえばfoo、現在 7500 行以上あるテーブルで問題が発生していますが、シーケンスがfoo_id_seqオンcurrent valueに設定されてい5ます (挿入を 5 回試行しましたが、すべて失敗したためです)。

質問:

idだから私の質問は、ステートメントで ,を明示的に指定せずにINSERT、どうすれば Postgres に一意の値をidフィールド ifに自動的に割り当てることができるかということfooです。またはより具体的には、シーケンスに一意の値を返すようにしますか?

砂糖:

SQLAlchemy インターフェースを介してこれらすべてを実現します。

環境の詳細:

  • パイソン 2.6
  • SQLAlchemy 8.2
  • PostgreSQL 9.2
  • psycopg2 - 2.5.1 (dt dec pq3 ext)

PS: この質問により適切なタイトルを見つけた場合は、編集してください。

4

2 に答える 2

1

aを aとしてPRIMARY KEY使用するように定義する必要があります。これには、便利な疑似型を使用します。SEQUENCEDEFAULTSERIAL

CREATE TABLE blah (
    id serial primary key,
    ...
);

または明示的なSEQUENCE:

CREATE SEQUENCE blah_id_seq;

CREATE TABLE blah (
    id integer primary key default nextval('blah_id_seq'),
    ...
);

ALTER SEQUENCE blah_id_seq OWNED BY blah.id;

これについては、SQLAlchemy のドキュメントで説明されています。

これを既存のテーブルに追加できます。

CREATE SEQUENCE blah_id_seq OWNED BY blah.id;

ALTER TABLE blah ALTER COLUMN id SET DEFAULT nextval('blah_id_seq');

ダンプを復元したい場合は、シーケンスを手動で追加してください。

テーブルに直接ロードした既存のデータがある場合はCOPY、シーケンスの開始点を設定する必要があります。

SELECT setval('blah_id_seq', max(id)+1) FROM blah;

問題は、SQLite での開発、ダンプの実行、およびそのダンプの PostgreSQL への復元に関係している可能性が高いと思います。SQLAlchemy は、適切なデフォルトとシーケンスを使用してスキーマ自体を作成することを想定しています。

代わりに、SQLAlchemy を使用して新しい空のデータベースを作成することをお勧めします。各テーブルのデータを SQLite DB から CSV にダンプし、COPYそのデータを PostgreSQL テーブルにダンプします。最後に、シーケンスを更新してsetval、適切な値を生成します。

いずれにせよ、適切なシーケンスが作成されていることを確認する必要があります。SERIAL疑似列タイプ、または手動でSEQUENCE作成および設定することDEFAULTで実行できますが、実行する必要があります。そうしないと、生成された ID を、効率的で同時実行セーフな方法でテーブルに割り当てる方法がありません。

于 2013-07-18T01:44:16.507 に答える
0

使用する

alter sequence foo_id_seq restart with 7600

次にシーケンスを呼び出したときに 7601 が返されるはずです。

http://www.postgresql.org/docs/current/static/sql-altersequence.html

そして、その後の値。値>最後のIDで再起動してください。

于 2013-07-17T11:28:37.130 に答える