我定制了一个基础模型
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)
自 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、当前模型。