web-dev-qa-db-ja.com

自動インクリメントなしのsqlalchemy主キー

次のようなレイアウトでテーブルを作成しようとしています。

class Widget(db.Model):
    __tablename__ = 'widgets'
    ext_id = db.Column(db.Integer, primary_key=True)
    w_code = db.Column(db.String(34), unique=True)
    # other traits follow...

すべてのフィールド値は外部システムを通じて提供され、新しいウィジェットが検出され、省略された特性値の一部は時間の経過とともに(非常に徐々に)変化する可能性がありますが、ext_idとw_codeは一意であることが保証されます。 ext_idの値の性質を考えると、これは主キーとして理想的に動作します。

しかし、ext_id値を指定して新しいレコードを作成すると、その値はストレージで使用されません。代わりに、ext_idの値は自動インクリメント動作に従います。

>>> # from a clean database
>>> skill = Widget(ext_id=7723, w_code=u'IGF35ac9')
>>> session.add(skill)
>>> session.commit()
>>> Skill.query.first().ext_id
1
>>> 

自動インクリメントなしでext_idフィールドを主キーフィールドとして使用するようにSQLAlchemyに指定するにはどうすればよいですか?

注:主キーとして追加の合成ID列を追加し、代わりにext_idを一意の列にすることもできますが、これによりコードが複雑になり、(最小限の)追加の膨張がデータベースとすべてのI/Oに追加されます。それを避けたいです。

問題は大きなプロジェクトから発生しましたが、小さな再現を作成することができました。

SQLiteを使用したテスト

23
stevelle

セットする - autoincrement=False 主キーのシーケンスまたはシリアルの作成を無効にします。

ext_id = db.Column(db.Integer, primary_key=True, autoincrement=False)
37
davidism