如何使用sqlalchemy.orm声明列的顺序?

问题描述 投票:0回答:1

我定制了一个基础模型

CoModel
,它声明了
created_time
updated_time
的属性。

但是如何固定声明列的顺序?

我希望

created_time
updated_time
成为创建表格时的最后两列。

from datetime import datetime    
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.ext.declarative import declared_attr


session_options = dict(
    bind=None,
    autoflush=False,
    autocommit=False,
    expire_on_commit=False,
)
db = SQLAlchemy(session_options=session_options)


class CoModel():
    """ sample:
    class TableName(db.Model, CoModel):
        pass
    """

    @declared_attr
    def created_time(self):
        return db.Column(db.DateTime, default=datetime.utcnow)

    @declared_attr
    def updated_time(self):
        return db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
python mysql orm sqlalchemy flask-sqlalchemy
1个回答
0
投票

SQLAlchemy 2.0.4 起,mapped_column 有一个 sort_order 参数,该参数控制由

CREATE TABLE
生成的
Metadata.create_all
语句中列的相对位置。
sort_order
默认为 0,但可以是任何正整数或负整数。

默认情况下,v2.x 中的列顺序是从当前类声明的列,然后是超类和 mixins 中的列,按照这些类在

class
语句中声明的顺序。

例如这些型号:

class Base(orm.DeclarativeBase):
    pass


class MyBase(Base):
    __abstract__ = True

    id: Mapped[int] = mapped_column(primary_key=True)
    mb_col: Mapped[int]


class Mixin:
    mix_col: Mapped[int]


class MyTable(MyBase):
    __tablename__ = 'my_table'

    mt_col: Mapped[int]


class MyMixedTable(Mixin, MyBase):
    __tablename__ = 'my_mixed_table'

    mmt_col: Mapped[int]


class MyTableMixed(MyBase, Mixin):
    __tablename__ = 'my_table_mixed'

    mtm_col: Mapped[int]

会生成这个DDL:

CREATE TABLE my_table (
    mt_col INTEGER NOT NULL, 
    id INTEGER NOT NULL, 
    mb_col INTEGER NOT NULL, 
    PRIMARY KEY (id)
)



CREATE TABLE my_mixed_table (
    mmt_col INTEGER NOT NULL, 
    mix_col INTEGER NOT NULL, 
    id INTEGER NOT NULL, 
    mb_col INTEGER NOT NULL, 
    PRIMARY KEY (id)
)



CREATE TABLE my_table_mixed (
    mtm_col INTEGER NOT NULL, 
    id INTEGER NOT NULL, 
    mb_col INTEGER NOT NULL, 
    mix_col INTEGER NOT NULL, 
    PRIMARY KEY (id)
)

但是,如果所需的顺序是超类、当前模型、mixins,那么这些模型声明:

class Base(orm.DeclarativeBase):
    pass


class MyBase(Base):
    __abstract__ = True

    id: Mapped[int] = mapped_column(primary_key=True, sort_order=-10)
    mb_col: Mapped[int] = mapped_column(sort_order=-1)


class Mixin:
    mix_col: Mapped[int] = mapped_column(sort_order=3)


class MyTable(MyBase):
    __tablename__ = 'my_table'

    mt_col: Mapped[int] = mapped_column()


class MyMixedTable(Mixin, MyBase):
    __tablename__ = 'my_mixed_table'

    mmt_col: Mapped[int] = mapped_column()


class MyTableMixed(MyBase, Mixin):
    __tablename__ = 'my_table_mixed'

    mtm_col: Mapped[int] = mapped_column()

将生成这个DDL:

CREATE TABLE my_table (
    id INTEGER NOT NULL, 
    mb_col INTEGER NOT NULL, 
    mt_col INTEGER NOT NULL, 
    PRIMARY KEY (id)
)



CREATE TABLE my_mixed_table (
    id INTEGER NOT NULL, 
    mb_col INTEGER NOT NULL, 
    mmt_col INTEGER NOT NULL, 
    mix_col INTEGER NOT NULL, 
    PRIMARY KEY (id)
)



CREATE TABLE my_table_mixed (
    id INTEGER NOT NULL, 
    mb_col INTEGER NOT NULL, 
    mtm_col INTEGER NOT NULL, 
    mix_col INTEGER NOT NULL, 
    PRIMARY KEY (id)
)

对于早期版本(2.0 之前),生成的列顺序是超类、mixin、当前模型。

© www.soinside.com 2019 - 2024. All rights reserved.