284

SQLAlchemy で生の SQL をどのように実行しますか?

フラスコで実行され、SQLAlchemy を介してデータベースに接続する Python Web アプリがあります。

生の SQL を実行する方法が必要です。クエリには、インライン ビューと共に複数のテーブル結合が含まれます。

私はもう試した:

connection = db.session.connection()
connection.execute( <sql here> )

しかし、ゲートウェイエラーが発生し続けます。

4

9 に答える 9

376

やってみました:

result = db.engine.execute("<sql here>")

また:

from sqlalchemy import text

sql = text('select name from penguins')
result = db.engine.execute(sql)
names = [row[0] for row in result]
print names

SQLAlchemy 2.0 で廃止されたdb.engine.execute()「コネクションレス」であることに注意してください。

于 2013-08-01T07:32:51.480 に答える
243

SQL Alchemy セッション オブジェクトには独自のexecuteメソッドがあります。

result = db.session.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})

すべてのアプリケーション クエリは、生の SQL であるかどうかにかかわらず、セッション オブジェクトを経由する必要があります。これにより、クエリがトランザクションによって適切に管理され、同じリクエスト内の複数のクエリを 1 つの単位としてコミットまたはロールバックできるようになります。エンジンまたは接続を使用してトランザクションの外に出ると、微妙な、場合によっては検出が困難なバグのリスクがはるかに高くなり、データが破損する可能性があります。各リクエストは 1 つのトランザクションのみに関連付ける必要がありdb.sessionます。

パラメータ化されたクエリexecute用に設計されていることにも注意してください。SQL インジェクション攻撃から身を守るために、例のようにクエリへの入力にパラメーターを使用します。これらのパラメーターの値は、2 番目の引数として a を渡すことで指定できます。各キーは、クエリに表示されるパラメーターの名前です。パラメータ自体の正確な構文はデータベースによって異なる場合がありますが、主要なリレーショナル データベースはすべて何らかの形でサポートしています。:valdict

SELECTクエリであると仮定すると、これは反復可能RowProxyオブジェクトを返します。

さまざまな手法で個々の列にアクセスできます。

for r in result:
    print(r[0]) # Access by positional index
    print(r['my_column']) # Access by column name as a string
    r_dict = dict(r.items()) # convert to dict keyed by column names

namedtuple個人的には、結果をsに変換することを好みます。

from collections import namedtuple

Record = namedtuple('Record', result.keys())
records = [Record(*r) for r in result.fetchall()]
for r in records:
    print(r.my_column)
    print(r)

Flask-SQLAlchemy 拡張機能を使用していない場合でも、セッションを簡単に使用できます。

import sqlalchemy
from sqlalchemy.orm import sessionmaker, scoped_session

engine = sqlalchemy.create_engine('my connection string')
Session = scoped_session(sessionmaker(bind=engine))

s = Session()
result = s.execute('SELECT * FROM my_table WHERE my_column = :val', {'val': 5})
于 2014-02-28T01:56:51.210 に答える
57

ここに示すようにfrom_statement()、 とを使用して SELECT SQL クエリの結果を取得できます。この方法でタプルを扱う必要はありません。試すことができるテーブル名を持つクラスの例として、text()Userusers

from sqlalchemy.sql import text

user = session.query(User).from_statement(
    text("""SELECT * FROM users where name=:name""")
).params(name="ed").all()

return user
于 2014-11-03T12:39:44.250 に答える
14
result = db.engine.execute(text("<sql here>"))

を実行しますが、モード<sql here>でない限りコミットしません。autocommitしたがって、挿入と更新はデータベースに反映されません。

変更後にコミットするには、次のようにします

result = db.engine.execute(text("<sql here>").execution_options(autocommit=True))
于 2015-09-03T07:03:12.423 に答える
13

SQLAlchemy ≥ 1.4 の場合

SQLAlchemy 1.4 から、コネクションレスまたは暗黙の実行は非推奨になりました。

db.engine.execute(...) # DEPRECATED

クエリとしての生の文字列と同様に。

新しい API には明示的な接続が必要です。

from sqlalchemy import text

with db.engine.connect() as connection:
    result = connection.execute(text("SELECT * FROM ..."))
    for row in result:
        # ...

同様に、既存のセッションが利用可能な場合は、それを使用することをお勧めします。

result = session.execute(sqlalchemy.text("SELECT * FROM ..."))

またはパラメータを使用して:

session.execute(sqlalchemy.text("SELECT * FROM a_table WHERE a_column = :val"),
                {'val': 5})

詳細については、ドキュメントの「コネクションレス実行、暗黙的実行」を参照してください。

于 2021-05-06T14:44:20.483 に答える