kuroの覚え書き

96の個人的覚え書き

部分一致 AND, OR その他細々とした検索オプション

>>>SELECT * FROM User WHERE username Like %ki

というふうな部分一致検索をするなら

        user = user.filter(User.username.like(form.name.data))

このように.like()を使ってやって検索ワードに%kiを入力してやるといいようだ。

部分一致は検索に時間がかかるかもしれないので、場合によってはチェックボックスでオプション扱いにした方がいいかもしれない。その場合、まずform定義に

class ExomeForm(FlaskForm):
    name = StringField('Sample name')
    aname = BooleanField('use regex "ex. %part%"')

チェックボックスの定義を加え、検索の定義を

    if form.name.data:
        if form.aname.data:
             user = user.filter(User.username.like(form.name.data))
        else:
            user = user.filter_by(username=form.name.data)

こんな感じに更に分岐を足してやる。そうすれば完全一致でいい場合はシンプルなfilter_by()で検索されるので、検索速度があがると思われる。





複合検索条件の方だが、前もってfilterの条件を定義してしまうといいわけか。
ANDの場合

where = (User.username=='hoge') & (User.gene=='foo')
user = user.filter(where)

ORの場合

where = (User.username=='hoge') | (User.gene=='foo')
user = user.filter(where)

しかしこれじゃifと組み合わせるとかなりめんどくさいことになりそうな。
まあ、そもそもORやNOTが必要かどうか使ってみないとわからない部分もあるので、あまり深く突っ込んでここに時間をかけるのは、今は止めておく。


使うかどうかは別にして、各種機能を盛り込んだ最終盤はこちら

limitで表示する項目数を絞る。デフォルトは15。ゆるい条件で絞りすぎてべらぼうな行のリストが延々表示されるのを防ぐ。
offsetは1ページに収まりきらなかった(resultが50でlimitが20とか)スクロールの代わりに上位を飛ばして表示させる。まあなくても良さそうな機能。
sort機能はあったほうがいいかも。
class ExomeForm(FlaskForm):に

    order_by = SelectField('order by, default key = ID', choices=[('id', 'ID'), ('username', 'Username')])

そして
@app.route('/exome/', methods=['GET', 'POST'])に

    if form.order_by.data == 'id':
        user = user.order_by(User.id.asc())
    if form.order_by.data == 'username':
        user = user.order_by(User.username.asc())

ソートに使いたいキーは適当に追加してもいい。
なおorder_by()はlimitやoffsetよりも先に実行しておく必要があるので注意。