SQLAlchemy:向视图添加模型中未提及的新列是否安全?

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

例如,假设我有一个视图

create view MyView as select 1 as A, 2 as B

(上面的SQL是微软方言,但视图本身的细节并不重要。)

我将此视图包装在我的 SQLAlchemy 模型定义中:

class MyView(Base):
    __tablename__ = 'MyView'
    A = Column(Integer)
    B = Column(Integer)

该视图不仅在 SQLAlchemy 中使用。 其他应用程序或手写的 SQL 查询可能会使用它。 假设我想向视图添加一个新列,所以它现在显示为

create view MyView as select 1 as A, 2 as B, 3 as C

(这个新版本的视图对于大多数应用程序查询向后兼容。只有使用

select *
的查询才会看到不同的结果。将视图与其他视图或表连接的查询也提供名为
C
的列,但不完全限定列名,可能会出现有关不明确列名的错误。)

假设目前我不打算使用 SQLAlchemy 中的列

C
并且我不将其添加到模型定义中。 我最终可能会这样做,但无论出于何种原因,我现在还不能更改代码,或者至少不能发布新版本。 将列添加到视图并保持与现有 SQLAlchemy 模型文件兼容是否安全?

因为我询问的是视图,而不是表,所以请假设 SQLAlchemy 仅提供读取访问权限。 应用程序不会尝试更新视图或从视图中删除,即使这在某些 RDBMS 中是可能的。

如果 SQLAlchemy 尝试内省视图中的列并抱怨模型中未提及的其他列,那么不会有任何问题吗? 我认为不是......但我还没有找到明确的答案。

python view sqlalchemy
1个回答
0
投票

这应该没问题,只要您在映射中的视图中显式定义所需的列即可。 所以这个(你说你正在使用的)很好

class MyModel(Base):
    __tablename__ = 'my_view'
    
    id = Column(Integer, primary_key=True)
    col = Column(Integer)

因为映射器知道正在映射哪些列,并且只会在查询语句中使用这些列。

这样就不太好了:

my_view = Table('my_view', Base.metadata, autoload_with=engine)

class MyModel(Base):
    __table__ = my_view

因为映射器将使用反射表中的所有列。

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