使用SQLAlchemy ORM获取非主键,唯一的自动递增ID

时间:2017-01-08 08:27:34

标签: python mysql sqlalchemy flask-sqlalchemy

当我运行以下代码时,我希望first_name和last_name是一个复合主键,并且id是该行的自动增量索引,但不能作为主键,因为那里有信息在表的其余部分是我需要定义它的唯一性,而不是给定的ID。

Base = declarative_base()
Session = sessionmaker(bind=db)
session = Session()

class Person(Base):
    __tablename__ = "people"
    id = Column(Integer, index=True, unique=True, autoincrement=True, primary_key=False)
    first_name = Column(String(30), primary_key=True)
    last_name = Column(String(30), primary_key=True)

if __name__ == "__main__":
    Base.metadata.create_all(db)
    session.add_all([
        Person(first_name="Winston", last_name="Moy"),
        Person(first_name="Bill", last_name="Gates"),
        Person(first_name="Steve", last_name="Jobs"),
        Person(first_name="Quinten", last_name="Coldwater")
    ])
    session.commit()

问题我在DataGrip中查看结果,我得到了下表。数据不是按顺序添加的,而id列是null,而不是我期望的自动递增整数。 Image of person table

要明确:我的问题是:如何为不是主键的SQLAlchemy ORM类创建自动递增索引?

2 个答案:

答案 0 :(得分:4)

在撰写本文时,SQLAlchemy 1.1不支持在非主键字段上自动递增。

答案 1 :(得分:0)

这里是 mysql 的工作区:

sqlalchemy 创建表后,
手动更改表(添加 AUTO_INCREMENT 属性)使用 DDL。
(在表 after_create 事件)。

然后它会按需create_all()

一样执行

测试代码 (1.4.x):

from sqlalchemy.ext.declarative import declarative_base

# --- 1. define table
base = declarative_base()
class store(base):
    __tablename__ = 'store'
    id  = Column(Integer,    autoincrement=True, unique=True, primary_key=False) # AI here not work

    did = Column(String(64), unique=False, nullable=False)
    fid = Column(String(64), unique=False, nullable=False)

    __table_args__ = (
        PrimaryKeyConstraint('did', 'fid', name='idx_did_fid'),
    )


print(store)

# --- 2. fix autoincre on non-primary key // will execute as need, like create_all() dose
from sqlalchemy import event, DDL
event.listen(
    base.metadata, 'after_create',  DDL('ALTER TABLE `store` CHANGE `id` `id` INT(11) NULL DEFAULT NULL AUTO_INCREMENT')
)

# --- 3. create table as need
base.metadata.create_all(engine)