web-dev-qa-db-ja.com

SQLAlchemyを使用して1つの列のみを選択するにはどうすればよいですか?

「where句」を使用して、データベースから1つのフィールドのみを選択(および戻り)したい。コードは次のとおりです。

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」は正しいオプションですか?

13
user1903663

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() は、結果を1つだけ返すか、例外を発生させます(0または複数の結果)。 「ユーザーが見つかりません」の有効な戻り値としてNoneを受け入れる場合は、 one_or_none() を使用します。

WHERE句の条件である述語は、エンティティとしてQueryオブジェクトに渡されるべきではなく、 filter() で追加されることに注意してください。

最後に、Flask=のビューは、次のいずれかを返すことを期待しています:

  • 有効な応答オブジェクト
  • 文字列
  • _(response, status, headers)_タプル
  • wSGIアプリケーション

機械は、応答オブジェクト、文字列、またはタプル以外のものをWSGIアプリケーションとして扱います。元のコードでは、scalar()への呼び出しがないなどの理由でQueryオブジェクトを返しましたが、これはWSGIアプリとして扱われました。

36
Ilja Everilä

これらの線に沿って何かをする必要があります:

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

問題は、クエリとデータベース接続とは関係ありません。 @ application.route( "/ user"、methods = ['GET'、 'POST'])ステートメント内で、データベースからの選択の結果であるuser_idを返します。 Flaskで何かを返す必要があります 適切な

2
Alexey Smirnov

フラスコ-sqlalchemyテーブル全体ではなく1つの列のコンテンツをクエリすると、sqlalchemy自体が機能するというヒントが得られると思いますが、別の構文を使用して、実行中のセッションをクエリできます。

テーブルが次のように見える場合:

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

以下でクエリできます:

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

これは、すべてのユーザーIDのリストを返します。

2
ciacicode