如何让 Sqlalchemy 在它生成的 sql 中保留列顺序?

k10*_*107 6 python sqlalchemy

Sqlalchemy 在为表生成 sql 时似乎没有保留列顺序。如何让 sqlalchemy 使用与定义列相同的顺序?

例子:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Table, MetaData, Column, BigInteger, Integer, String, MetaData, ForeignKey, Date, DateTime

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
Base = declarative_base()


class MyTable(Base):
    __tablename__ = "my_table"

    id = Column(BigInteger, primary_key=True)
    col1 = Column(String(20), name="col1")
    col2 = Column(Integer)
    col3 = Column(BigInteger, name="col_3")

engine = create_engine('sqlite:///foo.db')
Session = sessionmaker(engine)
db = Session()

print(db.query(MyTable).statement.compile(engine))
Run Code Online (Sandbox Code Playgroud)

输出是:

SELECT my_table.col_3, my_table.id, my_table.col1, my_table.col2
FROM my_table
Run Code Online (Sandbox Code Playgroud)

代替

SELECT my_table.id, my_table.col1, my_table.col2, my_table.col_3
FROM my_table
Run Code Online (Sandbox Code Playgroud)

Sqlalchemy 似乎确实保留了表定义中的列顺序,因为当它生成 CREATE TABLE 命令时,列顺序与定义的列顺序匹配。

from sqlalchemy.schema import CreateTable
print(CreateTable(MyTable.__table__).compile(engine))
Run Code Online (Sandbox Code Playgroud)

dav*_*ism 4

列在映射器中的存储方式与表中的存储方式不同。当你CreateTable(MyTable.__table__)这样做时,它会在桌子上查看columns。当你session.query(MyTable)这样做时,它会查看_props当前的映射器_props的填充方式与 不同columns,并且由于 SQLAlchemy 内部的某些决定,这可能会导致不同的顺序。

答案最终是否定的,您无法保证查询列的顺序,因为还有其他力量在幕后起作用。如果顺序对您来说确实很重要,那么它可能应该作为针对 SQLAlchemy 的问题提出

在这种情况下,指定与属性名称不匹配的列名称会更改该列在内部存储的顺序。name='col_3'从该列中删除将“修复”此问题。