我試圖讓這個查詢運行,但它不像我預期的那樣作業。
表格中有一個日期欄位格式為文本(無法更改),我需要過濾此列。
日期看起來像
11/03/2022 (d/m/Y)
我的查詢看起來像
session.query(DBGEUK)\
.filter(DBGEUK.VALIDATOR == '58')\
.filter(func.CDate(DBGEUK.DATE) <= datetime.now())\
.all()
共有24個條目。當我運行上面的查詢并列印出 DBGEUK.DATE datetime.now 時,這 9 個條目是我的結果。
27/03/2022 2022-03-28 19:06:49.465406
27/03/2022 2022-03-28 19:06:49.480988
27/03/2022 2022-03-28 19:06:49.480988
27/03/2022 2022-03-28 19:06:49.480988
28/03/2022 2022-03-28 19:06:49.480988
28/03/2022 2022-03-28 19:06:49.480988
28/03/2022 2022-03-28 19:06:49.480988
28/03/2022 2022-03-28 19:06:49.481612
28/03/2022 2022-03-28 19:06:49.481727
如果我將查詢更改為更大,則 >= 我得到了其他 15 個條目
04/03/2022 2022-03-28 19:09:09.030659
04/03/2022 2022-03-28 19:09:09.031659
04/03/2022 2022-03-28 19:09:09.031659
04/03/2022 2022-03-28 19:09:09.031659
04/03/2022 2022-03-28 19:09:09.031659
05/03/2022 2022-03-28 19:09:09.031659
05/03/2022 2022-03-28 19:09:09.031659
05/03/2022 2022-03-28 19:09:09.031659
05/03/2022 2022-03-28 19:09:09.032657
11/03/2022 2022-03-28 19:09:09.032657
12/03/2022 2022-03-28 19:09:09.032657
11/03/2022 2022-03-28 19:09:09.032657
11/03/2022 2022-03-28 19:09:09.032657
09/03/2022 2022-03-28 19:09:09.033654
09/03/2022 2022-03-28 19:09:09.033654
感謝您在高級方面的幫助。
uj5u.com熱心網友回復:
該CDate()函式嘗試根據 Windows 控制面板中的日期格式設定來解釋日期字串文字。如果“短日期”設定為MM/dd/yyyy,則CDate("03/07/2022")計算結果為 2022 年 3 月 7 日。如果“短日期”設定為dd/MM/yyyy,CDate("03/07/2022")計算結果為 2022 年 7 月 3 日。
但是,如果日期字串表示無效日期,那么CDate()將是“有用的”并使用其他格式回傳有效日期。在上述兩種情況下,CDate("14/03/2022")將評估到 2022 年 3 月 14 日。
不幸的是,這意味著
- 日期的解釋方式取決于 Windows 日期格式,它可能因機器而異,甚至因同一機器上的用戶而異。
- 日期的解釋在模糊和明確的日期字串之間可能不一致。
因此,在這種情況下,我們需要避免CDate()自己使用和決議日期字串:
from datetime import datetime
from sqlalchemy import create_engine, Column, String, select, func
from sqlalchemy.engine import URL
from sqlalchemy.orm import declarative_base, Session
accdb_path = r"C:\Users\Public\test\sqlalchemy-access\gord_test.accdb"
connection_string = (
"DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};"
f"DBQ={accdb_path};"
"ExtendedAnsiSQL=1;"
)
connection_url = URL.create(
"access pyodbc", query={"odbc_connect": connection_string}
)
engine = create_engine(connection_url)
Base = declarative_base()
class DBGEUK(Base):
__tablename__ = "so71651145"
DATE = Column(String(10), primary_key=True)
def __repr__(self):
return f"<DBGEUK(DATE='{self.DATE}')>"
# create test environment
Base.metadata.drop_all(engine)
Base.metadata.create_all(engine)
with Session(engine) as session:
# example data
session.add_all(
[
# How CDate() interprets the string
# based on Windows' short date format:
#
# dd/MM/yyyy MM/dd/yyyy
# ------------ ------------
DBGEUK(DATE="07/03/2022"), # Mar 7, 2022 Jul 3, 2022
DBGEUK(DATE="14/03/2022"), # Mar 14, 2022 Mar 14, 2022
DBGEUK(DATE="03/07/2022"), # Jul 3, 2022 Mar 7, 2022
DBGEUK(DATE="31/12/2022"), # Dec 31, 2022 Dec 31, 2022
]
)
session.commit()
# (for future readers of this answer)
print(datetime.now()) # 2022-03-29 08:44:00.512366
# original query
qry = select(DBGEUK).filter(func.CDate(DBGEUK.DATE) <= datetime.now())
results = session.execute(qry).all()
print(results)
# [(<DBGEUK(DATE='14/03/2022')>,), (<DBGEUK(DATE='03/07/2022')>,)]
#
# with Windows' short date format set to MM/dd/yyyy, CDate() interprets
# the second value as March 7, not July 3
# corrected query
qry = select(DBGEUK).filter(
func.DateSerial(
func.CInt(func.Mid(DBGEUK.DATE, 7, 4)), # year
func.CInt(func.Mid(DBGEUK.DATE, 4, 2)), # month
func.CInt(func.Mid(DBGEUK.DATE, 1, 2)), # day
)
<= datetime.now()
)
results = session.execute(qry).all()
print(results)
# [(<DBGEUK(DATE='07/03/2022')>,), (<DBGEUK(DATE='14/03/2022')>,)]
#
# all good
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/453962.html
標籤:Python 毫秒访问 sqlalchemy sqlalchemy 访问
