SQLAlchemy func 淺解與日期格式

Posted on  Apr 8, 2020  in  Python 模組/套件推薦  by  Amo Chen  ‐ 2 min read

使用 SQLAlchemy 的時候,用到日期格式時都不免要查詢如何使用,因此將使用方法乾脆記錄下來,並且將有疑問的地方也給一併釐清。

本文環境

  • Python 3.6.5
  • SQLAlchemy 1.3.9

本文使用的 models

from sqlalchemy import create_engine
from sqlalchemy import Column, String, Integer, DateTime, ForeignKey
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()


class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    username = Column(String)
    password = Column(String)
    created = Column(DateTime)
    updated = Column(DateTime)


engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session() 

p.s. 此處以 SQLite 作為資料庫。

func

SQLAlchemy 將 SQL 函式(function) 都以 func 產生,譬如:

>>> from sqlalchemy.sql.expression import func
>>> print(func.count(1))
count(:count_1)
>>>
>>> print(func.count(User.id))
count("user".id)

上述的範例可以看到 func.count(1)func.count(User.id) 最後被轉為 SQL 中的 count 函式。

而且文件告訴我們 func 其實是一個 object ,而且會根據 func 的屬性名稱產生相對應的 SQL 函式:

func is a special object instance which generates SQL functions based on name-based attributes

也因此你可以簡單地使用 func.<你要使用的 SQL 函式> 就能夠呼叫 任何 想使用的 SQL 函式:

>>> print(func.CALLMEBABY('Hi'))
CALLMEBABY(:CALLMEBABY_1)

上述可以看到 func 真的只是負責產生 SQL 函式而已,並沒有驗證是否存在這樣的 SQL 函式,所以使用時必須自行確認你使用的資料庫有該項函數可以使用。

有興趣看 func 的原始碼的話,可以到 SQLAlchemy 的 Github repository 搜尋 _FunctionGenerator

日期格式

知道如何透過 func 產生 SQL 函式之後,要使用日期格式就簡單多了,直接看範例:

MySQL

print(
    session.query(
        User.id,
        func.date_format(User.created, "%Y-%m-%d %H:%i:%s")
    )
)

上述產生的 SQL 語法為:

SELECT user.id AS user_id, date_format(user.created, ?) AS date_format_1 
FROM user

其中 date_format(user.created, ?) 就是我們想使用 MySQL 的日期格式函式。

SQLite

print(
    session.query(
        User.id,
        func.strftime(User.created, "%Y-%m-%d %H:%M:%S")
    )
)

上述產生的 SQL 語法為:

SELECT user.id AS user_id, strftime(user.created, ?) AS strftime_1 
FROM user

其中 strftime(user.created, ?) 就是我們想使用 SQLite 的日期格式函式。

以上就是本文的內容。

Happy coding!

References

https://www.sqlalchemy.org/

對抗久坐職業傷害

研究指出每天增加 2 小時坐著的時間,會增加大腸癌、心臟疾病、肺癌的風險,也造成肩頸、腰背疼痛等常見問題。

然而對抗這些問題,卻只需要工作時定期休息跟伸展身體即可!

你想輕鬆改變現狀嗎?試試看我們的 PomodoRoll 番茄鐘吧! PomodoRoll 番茄鐘會根據你所設定的專注時間,定期建議你 1 項辦公族適用的伸展運動,幫助你打敗久坐所帶來的傷害!

贊助我們的創作

看完這篇文章了嗎? 休息一下,喝杯咖啡吧!

如果你覺得 MyApollo 有讓你獲得實用的資訊,希望能看到更多的技術分享,邀請你贊助我們一杯咖啡,讓我們有更多的動力與精力繼續提供高品質的文章,感謝你的支持!