【问题标题】:Retrieving all columns but some with SQLAlchemy使用 SQLAlchemy 检索除某些列外的所有列
【发布时间】:2021-11-21 15:24:44
【问题描述】:

我正在制作一个以 JSON 格式发送特定表的 WebService。 我使用 SQLAlchemy 与数据库进行通信。

我只想检索用户有权查看的列。

有没有办法告诉 SQLAlchemy 不检索某些列? 这是不正确的,但类似这样:

SELECT * EXCEPT column1 FROM table.

我知道可以在 SELECT 语句中只指定一些列,但这并不是我想要的,因为我不知道所有表列。我只想要除一些之外的所有列。

我也尝试获取所有列并删除我不想要的列属性:

 result = db_session.query(Table).all()
 for row in result:
     row.__delattr(column1)

但似乎 SQLAlchemy 不允许这样做。 我收到警告:

Warning: Column 'column1' cannot be null 
cursor.execute(statement, parameters)
ok

对你们来说最优化的方法是什么?

谢谢

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    您可以将表中的所有列(不想要的列除外)传递给查询方法。

    session.query(*[c for c in User.__table__.c if c.name != 'password'])
    

    这是一个可运行的示例:

    #!/usr/bin/env python
    
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String
    from sqlalchemy.orm import Session
    
    
    Base = declarative_base()
    class User(Base):
        __tablename__ = 'users'
    
        id = Column(Integer, primary_key=True)
        name = Column(String)
        fullname = Column(String)
        password = Column(String)
    
        def __init__(self, name, fullname, password):
            self.name = name
            self.fullname = fullname
            self.password = password
    
        def __repr__(self):
           return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)
    
    engine = create_engine('sqlite:///:memory:', echo=True)
    
    Base.metadata.create_all(engine)
    session = Session(bind=engine)
    ed_user = User('ed', 'Ed Jones', 'edspassword')
    session.add(ed_user)
    session.commit()
    
    result = session.query(*[c for c in User.__table__.c if c.name != 'password']).all()
    print(result)
    

    【讨论】:

    • 唯一不好的是你会丢失类型和属性名,因为它返回一个元组。
    • User.columns() 也返回与User.__table__.c 相同的输出
    【解决方案2】:

    您可以将该列设为延迟列。此功能允许仅在直接访问时加载表的特定列,而不是在使用 Query 查询实体时加载。

    Deferred Column Loading

    【讨论】:

      【解决方案3】:

      这对我有用

       users = db.query(models.User).filter(models.User.email != current_user.email).all()
       return users
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-27
        • 2018-02-01
        • 2015-10-18
        • 2021-06-29
        • 2016-03-07
        • 1970-01-01
        • 2020-03-25
        • 2019-01-17
        相关资源
        最近更新 更多