如何使用SQLAlchemy只选择一列?

时间:2016-05-10 09:01:47

标签: python flask sqlalchemy

我想仅使用“where子句”从我的数据库中选择(并返回)一个字段。代码是:

from sqlalchemy.orm import load_only
    @application.route("/user", methods=['GET', 'POST'])
    def user():
        user_id = session.query(User, User.validation==request.cookies.get("validation")).options(load_only("id"))
        session.commit()
        return user_id

此操作失败,回溯为:

File "/Library/Python/2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Library/Python/2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Library/Python/2.7/site-packages/flask/app.py", line 1478, in full_dispatch_request
response = self.make_response(rv)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1577, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/Library/Python/2.7/site-packages/werkzeug/wrappers.py", line 841, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/Library/Python/2.7/site-packages/werkzeug/wrappers.py", line 57, in _run_wsgi_app
return _run_wsgi_app(*args)
File "/Library/Python/2.7/site-packages/werkzeug/test.py", line 867, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'Query' object is not callable

如何选择并返回“id”列?我也尝试了其他几种方法,但也失败了。 “load_only”是正确的选项吗?

5 个答案:

答案 0 :(得分:33)

Query对象接受实体作为位置参数进行查询,因此只需将其传递给User.id

user_id = session.query(User.id).\
        filter(User.validation == request.cookies.get("validation")).\
        scalar()
如果没有找到行,

scalar()将返回第一个结果的第一个元素或None。它为多行引发了MultipleResultsFound异常。

load_only()表示只应加载实体的给定的基于列的属性,并且所有其他属性(期望标识)将被延迟。如果您以后确实需要整个User模型对象,那么这可能就是您的选择。在这种情况下,您的原始查询必须更改为:

user = session.query(User).\
        filter(User.validation == request.cookies.get("validation")).\
        options(load_only("id")).\
        one()

one()只返回一个结果或引发异常(0或多于1个结果)。如果您接受None作为“未找到用户”的有效返回值,请使用one_or_none()

请注意,谓词(WHERE子句的条件)不应作为实体传递给Query对象,而应添加filter()

最重要的是,Flask中的视图希望您返回以下内容之一:

  • 有效的回复对象
  • 一个字符串
  • 一个(response, status, headers)元组
  • WSGI应用程序

机器会将响应对象,字符串或元组以外的任何内容视为WSGI应用程序。在原始代码中,您返回了一个Query对象,因为缺少对scalar()的调用,因此将其视为WSGI应用程序。

答案 1 :(得分:3)

注意:如果您致电Model.query(params),则会看到以下错误

ERROR: 'BaseQuery' object is not callable

您需要在query(params)上致电session

示例:

rows = session.query(Model.name).filter(Model.age >= 20).all()

替代:

您可以使用with_entities

示例:获取年龄大于20的姓名和年龄

rows = Model.query.with_entities(Model.name, Model.age).filter(Model.age >= 20).all()

答案 2 :(得分:2)

你必须按照这些方针做点什么:

session.query(Table.col1).filter(User.name=='Name')

答案 3 :(得分:2)

要查询一列的内容而不是整个表flask-sqlalchemy的内容,我想这可以给你一个关于sqlalchemy的提示本身可以让你按照不同的语法查询会话。

如果您的表格如下:

class User(...):
    id = db.Column(db.Integer, primary_key=True)
    ...

您可以使用以下方式查询:

user_ids = session.query(User.id)
all_ids = user_ids.all()

这将返回所有用户ID的列表。

答案 4 :(得分:2)

问题与查询和数据库连接无关。在@ application.route(“/ user”,methods = ['GET','POST'])语句中,您返回一个user_id,它是从数据库中选择的结果。在Flask中你应该返回一些appropriate