iT邦幫忙

0

Python SQlalchemy 或 Javascript 動態條件搜尋

  • 分享至 

  • xImage

假設有一組資料,類似下面
選擇搜尋條件時,可能不選(不設條件代表全部)或多選

id user state
1 test1 done
2 test1 done
3 test2 undone
4 test2 done
5 test3 undone

搜尋條件

user = [] or ["test1"] or ["test1", "test2"] or ...
state = [] or ["done"] or ["done", "undone"]

問題:
使用 SQlalchemy 或是其他方式(SQL 或是 Javascript)
可能在一種語句下去滿足這些可能嗎?不然就要用判斷式寫不同的語句了

例如 ? 依狀況代入
WHERE user = ? and state IN ?

各 1

user = ["test1"]
state = ["done"]
WHERE user = "test1" and state = "done"

結果
1 | test1 | done
2 | test1 | done

不選

user = []
state = ["undone"]
WHERE state = "done" # 省略 and

結果
3 | test2 | undone
5 | test3 | undone

多選

user = ["test1", "test2"]
state = ["done"]
WHERE user IN ("test1", "test2") and state = "done"

結果
1 | test1 | done
2 | test1 | done
4 | test2 | done

目前研究大概知道前面 2 種可以用 **kwargs 代入來避開 and
但列表要改用 in 時是否適用呢

query = {
    "user": "test1"
}

filter(**query) # 不行
filter_by(**query) # 可以
filter(user == "test1").filter(state ==??) # 不行

備註:補充,以 SQLAlchemy 來說
filter_by 才可以使用 **kwargs 代入
但語法只有簡單的相等比較,無法滿足較複雜的搜尋

參考 data

data = [
    {
    "id":1,
    "user":"test1",
    "state": "done"
    },
    {
    "id":2,
    "user":"test1",
    "state": "done"
    },
    {
    "id":3,
    "user":"test2",
    "state": "undone"
    },
    {
    "id":4,
    "user":"test2",
    "state": "done"
    },
    {
    "id":5,
    "user":"test3",
    "state": "undone"
    },
]

query = {
    "user": ["test1"],
    "state":["done", "undone"]
}
powerc iT邦新手 1 級 ‧ 2023-08-16 17:36:51 檢舉
我C#有接觸到odata,查了一下python也有套件,不過我只知道這個QQ
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
熊熊工程師
iT邦研究生 2 級 ‧ 2023-08-16 18:24:31
最佳解答

當使用 SQLAlchemy 進行查詢時,你可以使用 filter 方法來設定查詢條件。在這個例子中,我們將演示如何使用 in 和普通的相等條件,以及如何使用 **kwargs 傳入條件。

假設你有一個 SQLAlchemy 的模型叫做 User,並且這個模型有兩個屬性:idstatus。下面是一個查詢的範例:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from your_module import User  # 假設 User 是你的模型

# 建立資料庫連線
engine = create_engine('sqlite:///my_database.db')
Session = sessionmaker(bind=engine)
session = Session()

# 假設這是你從 **kwargs 中獲得的條件
query_conditions = {
    'id': [1, 2, 3],  # 用於 in 條件
    'status': 'active'  # 用於相等條件
}

# 建立查詢
query = session.query(User)

# 加入條件
if 'id' in query_conditions:
    query = query.filter(User.id.in_(query_conditions['id']))

if 'status' in query_conditions:
    query = query.filter(User.status == query_conditions['status'])

# 執行查詢並獲取結果
results = query.all()

# 輸出結果
for user in results:
    print(f"User ID: {user.id}, Status: {user.status}")

在這個範例中,我們使用了 filter 方法來添加查詢條件。如果 idquery_conditions 中存在,我們使用 User.id.in_() 來設定 in 條件;如果 statusquery_conditions 中存在,我們使用 User.status == 來設定相等條件。

這樣你就可以根據不同的查詢條件進行動態的查詢,並使用 **kwargs 來方便地傳入條件。

來自 GPT 的回答,供參考

hokou iT邦好手 1 級 ‧ 2023-08-16 21:00:19 檢舉

哈哈,不愧是 GPT
一本正經地頭尾都有提 **kwargs
然後中間內容卻沒有
但還是有提供一些想法,感謝

/images/emoticon/emoticon06.gif

1
froce
iT邦大師 1 級 ‧ 2023-08-17 10:10:18
query = {
    "user": ["test1"],
    "state":["done", "undone"]
}

query["user"] = User.id.in_(query["user"])
query["state"] = User.state.in_(query["state"])

filter(**query)

這樣不就好了...

題外話,django的orm就只要在前端的key改成 user_id__in,就可以直接用。

hokou iT邦好手 1 級 ‧ 2023-08-17 11:29:30 檢舉

感謝建議
Django 的 orm 似乎比較強大一點

froce iT邦大師 1 級 ‧ 2023-08-17 12:53:14 檢舉

剛剛想了一下,好像不能直接解開,filter那邊要改一下

filter(*query.values())

django的orm是比較簡單一點,但如果你需要全程都用ORM的話,好像還是SQlalchemy比較容易做更複雜的查詢。

我要發表回答

立即登入回答