簡體   English   中英

在 SQLAlchemy 中使用 OR

[英]Using OR in SQLAlchemy

瀏覽了文檔,但似乎無法找到如何在 SQLAlchemy 中進行 OR 查詢。 我只想做這個查詢。

SELECT address FROM addressbook WHERE city='boston' AND (lastname='bulger' OR firstname='whitey')

應該是這樣的

addr = session.query(AddressBook).filter(City == "boston").filter(????)

教程

from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))

SQLAlchemy 重載按位運算符& , | ~因此,您可以使用以下運算符,而不是帶有or_()和 and_( and_()的丑陋且難以閱讀的前綴語法(就像在Bastien 的回答中一樣):

.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))

請注意,由於位運算符的優先級,括號不是可選的。

因此,您的整個查詢可能如下所示:

addr = session.query(AddressBook) \
    .filter(AddressBook.city == "boston") \
    .filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))

or_()函數在 OR 查詢組件數量未知的情況下很有用。

例如,假設我們正在創建一個帶有少量可選過濾器的 REST 服務,如果任何過濾器返回 true,它應該返回記錄。 另一方面,如果請求中沒有定義參數,我們的查詢不應該改變。 如果沒有or_()函數,我們必須這樣做:

query = Book.query
if filter.title and filter.author:
    query = query.filter((Book.title.ilike(filter.title))|(Book.author.ilike(filter.author)))
else if filter.title:
    query = query.filter(Book.title.ilike(filter.title))
else if filter.author:
    query = query.filter(Book.author.ilike(filter.author))

使用or_()函數可以將其重寫為:

query = Book.query
not_null_filters = []
if filter.title:
    not_null_filters.append(Book.title.ilike(filter.title))
if filter.author:
    not_null_filters.append(Book.author.ilike(filter.author))

if len(not_null_filters) > 0:
    query = query.filter(or_(*not_null_filters))

對於 SQLAlchemy ORM 2.0 兩者| or_被接受。

文檔

from sqlalchemy.future import select
from sqlalchemy.sql import or_


query = select(User).where(or_(User.name == 'ed', User.name == 'wendy'))
print(query)

# also possible:

query = select(User).where((User.name == 'ed') | (User.name == 'wendy'))
print(query)

這真的很有幫助。 這是我對任何給定表的實現:

def sql_replace(self, tableobject, dictargs):

    #missing check of table object is valid
    primarykeys = [key.name for key in inspect(tableobject).primary_key]

    filterargs = []
    for primkeys in primarykeys:
        if dictargs[primkeys] is not None:
            filterargs.append(getattr(db.RT_eqmtvsdata, primkeys) == dictargs[primkeys])
        else:
            return

    query = select([db.RT_eqmtvsdata]).where(and_(*filterargs))

    if self.r_ExecuteAndErrorChk2(query)[primarykeys[0]] is not None:
        # update
        filter = and_(*filterargs)
        query = tableobject.__table__.update().values(dictargs).where(filter)
        return self.w_ExecuteAndErrorChk2(query)

    else:
        query = tableobject.__table__.insert().values(dictargs)
        return self.w_ExecuteAndErrorChk2(query)

# example usage
inrow = {'eqmtvs_id': eqmtvsid, 'datetime': dtime, 'param_id': paramid}

self.sql_replace(tableobject=db.RT_eqmtvsdata, dictargs=inrow)

如果您需要在滿足條件時應用條件,過濾器可以存儲在變量中並用管道鏈接它們。 這是一個例子

 class Student(db.Model):
     __tablename__ = "student"
     id = Column(Integer, primary_key=True)
     name = Column(String, nullable=False)

   def get_by_name(self, name):
      condition = # Code Here for condition
      filters = (Student.name == "Stack") | (Student.name == "Overflow") if 
condition else (Student.name == "Stack")
      query = Student.query.filter(filters).order_by(Student.id.asc())

如果你需要做AND查詢,你可以通過 coma 將條件作為不同的過濾器參數傳遞

user = db.query(User).filter(
    User.username == 'tony', 
    User.is_active == True
).first()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM