web-dev-qa-db-ja.com

列に部分文字列が含まれるSQLAlchemyクエリ

SQLAlchemyとSQLite3を使用してクエリを作成しています。このクエリでは、String列に特定のサブストリングが含まれている行を選択します。これを達成するための最良の方法は何ですか?

30
Dave

db.table.column.like('%needle%')でフィルタリングします。大文字と小文字を区別しない検索のためのilikeもあります。

より洗練されたインターフェースでは、既知の「dir」ワイルドカードを許可できます。

_if '*' in needle or '_' in needle: 
    looking_for = needle.replace('_', '__')\
                        .replace('*', '%')\
                        .replace('?', '_')
else:
    looking_for = '%{0}%'.format(needle)

result = db.table.filter(db.table.column.ilike(looking_for))
_

ノート:

  • _db.table.filter_および_db.table.column_はSQLSoup用です(データベースが別のアプリケーションによって作成された場合、 SQLSoup が役立ちます)
  • sQLAlchemy Coreの場合はselect(column_list).where(table.c.column.ilike(expr))です。このインターフェイスは、文字列補間を使用して手動でステートメントを作成することなく、生のSQLのすべての機能を必要とする場合に使用する方法です(イントロスペクションにはSQLSoupに沿って使用するため、テーブルを宣言する必要はありません)。
  • sQLAlchemy Declarative(Flaskで使用されるもの)の場合はModel.query.filter(Model.field.ilike(expr))です
30
Paulo Scardine

これを試して

Model.query.filter(Model.columnName.contains('sub_string'))
60
kartheek

table.c.column.like("%...%")は機能するはずですが、あなたが望むものを言うためのより直接的な方法があります:

table.c.column.contains("needle")

これは通常同じSQLクエリを生成しますが、開始されていない場合は読むことをお勧めします。 containsは"_"および"%"をエスケープしないようです。

13
Bluehorn
@app.route('/<var>', methods=['GET'])
def getdb(var):
    look_for = '%{0}%'.format(var)
    log1 = table.query.filter(table.col.like(look_for))

SQLAlchemyとFlask(上のapp.routeはデコレータ)を使用しました。getAPIを使用して、ユーザーが検索したい変数を取得し、それを変換しています。 format()を使用してlook_forと呼ばれる別の変数に変数を格納する変数(varはクエリで直接使用できないため)。log1は照会されたタプルを格納します。

2