Не удалось создать автоинкрементный первичный ключ с фляжкой-sqlalchemy

Я хочу, чтобы мой первичный ключ модели был автоинкрементным целым. Вот как моя модель выглядит как

class Region(db.Model):
    __tablename__ = 'regions'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(100))
    parent_id = db.Column(db.Integer, db.ForeignKey('regions.id'))
    parent = db.relationship('Region', remote_side=id, primaryjoin=('Region.parent_id==Region.id'), backref='sub-regions')
    created_at = db.Column(db.DateTime, default=db.func.now())
    deleted_at = db.Column(db.DateTime)

Вышеприведенный код создает мою таблицу, но не делает id автоинкремент. Поэтому, если в моем запросе на вставку я пропустил поле id, он дал мне эту ошибку

ОШИБКА: значение null в столбце "id" нарушает непустое ограничение

Итак, я изменил объявление id, чтобы выглядеть так:

id = db.Column(db.Integer, db.Sequence('seq_reg_id', start=1, increment=1),
               primary_key=True)

По-прежнему такая же ошибка. Что не так с кодом выше?

Ответы

Ответ 1

С приведенным выше кодом ничего не получается. На самом деле вам даже не нужны autoincrement=True или db.Sequence('seq_reg_id', start=1, increment=1),, поскольку SQLAlchemy автоматически установит первый столбец Integer PK, который не помечен как FK как autoincrement=True.

Здесь я собрал рабочую настройку, основанную на вашем. SQLAlechemy ORM позаботится о создании идентификатора и заполнении объектов с ними, если вы используете класс, основанный на декларативной основе, который вы определили для создания экземпляров вашего объекта.

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.debug = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:[email protected]/testdb'
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)

class Region(db.Model):
    __tablename__ = 'regions'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100))

db.drop_all()
db.create_all()

region = Region(name='Over Yonder Thar')
app.logger.info(region.id) # currently None, before persistence

db.session.add(region)
db.session.commit()
app.logger.info(region.id) # gets assigned an id of 1 after being persisted

region2 = Region(name='Yet Another Up Yar')
db.session.add(region2)
db.session.commit()
app.logger.info(region2.id) # and 2

if __name__ == '__main__':
    app.run(port=9001)

Ответ 2

Я думаю, что вам не нужен автоинкремент, как только вы установите,

id = db.Column(db.Integer , primary_key=True , autoincrement=True)

Я думаю, что так и должно быть,

id = db.Column(db.Integer , primary_key=True)

это даст вам уникальность, которую вы ищете.

Ответ 3

У меня была такая же проблема, используя колбу-sqlalchemy и postgresql. Я смог решить это, изменив столбец id на следующее:

id = db.Column(db.Integer, primary_key=True, default=lambda: uuid.uuid4().hex)