SQLAlchemy ORM 參考

來源:互聯網
上載者:User

標籤:http   io   ar   os   使用   sp   java   strong   on   

ORM Session
from sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerengine = create_engine(‘sqlite:///:memory:‘, echo=False)Session = sessionmaker(bind=engine)session = Session()

echo 負責設定是否輸出產生的 SQL 陳述式。

create_engine 返回的是一個 Engine 對象,它負責對接 DBAPI。Session 對象會更多被直接使用。

session 某種意義上類似於一個緩衝,他有 commit, rollback, close 等方法。也因此 session 執行個體的生命週期維護應該位於使用它們的函數之外,與具體的應用邏輯區分開,以避免資料汙染和保證 rollback/close 的調用。如:– 參考

from contextlib import contextmanager@contextmanagerdef session_scope():    """Provide a transactional scope around a series of operations."""    session = Session()    try:        yield session        session.commit()    except:        session.rollback()        raise    finally:        session.close()def run_my_program():    with session_scope() as session:        ThingOne().go(session)        ThingTwo().go(session)
映射對象的聲明
from sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column, Integer, StringBase = declarative_base()class User(Base):    __tablename__ = ‘user‘    id = Column(Integer, primary_key=True)    name = Column(String)

從 Python 類到 sql 表,需要一套映射邏輯,sqlalchemy 提供了一套預設的解決方案,就是 declarative_base。

這裡單獨的一行 Base=declarative_base() 表示了你可以有很多種方式自訂基類,比如繼承 Base,或者給 declarative_base(**kwargs) 傳參。– 參考

至於 User 類,由於 sqlalchemy 預設不會去做任何推導,你需要顯示指定 __tablename__ 參數和至少一個主鍵。

Integer 類型沒有指定長度,是因為這種修飾參數僅在建表時有用。

Query new
tim = User(name=‘tim‘)session.add(tim)session.flush()

sqlalchemy 對待請求的處理方式是惰性的,他只在必要的時候才訪問資料庫。必要的一種定義是 query:

session.query(User).filter_by(name=‘tim‘)

立即同步到資料庫的方式是使用 .flush() 方法。

另外一個非常有趣的特性是,sqlalchemy 能夠在同一個 session 中分別出表記錄的唯一性。即:

>>> tim is session.query(User).filter_by(name=‘tim‘)>>> True

對於同一條資料庫記錄,不管是你建立的,還是多次從庫中取出的,他們的 Python id 都是一樣的。這種區分就是前面提到的 映射聲明必須提供主鍵 所帶來的一個好處。

query 對象

query() 的參數可以很多變,可以是一個 Model 類,或他的某些屬性的組合:

foo = session.query(User, User.id).filter(User.name==‘tim‘).first()

這種 query 方式返回的元組對象都是關鍵字命名的,而且支援屬性式訪問,如:

>>> foo.User.id == foo.id>>> True

如果想起別名,可以使用 .label() 方法:

>>> foo = session.query(User.id.label(‘user_id‘)).filter_by(name=‘tim‘)>>> foo.user_id>>> 1

對於 LIMIT 和 OFFSET 參數,可以直接對 Query 對象使用 Python 切片操作。

session.query(User)[20:10]

最後,Query 對象是可迭代的。儘管上面的例子為了偷懶沒有使用過迭代方法,但它是支援的!

filter

filter() 較於 filter_by() 是一種更通用的方法,支援所有的 sql 運算式。filter() 返回的仍然是一個 Query 對象,所以你可以連續調用 filter() 方法,或者圖省事把複合查詢語句放進同一個 filter() 裡

session.query(User).filter(id>1, name==‘tim‘)session.query(User).filter(id>1).filter(name==‘tim‘)

一些常用的運算式語句:

  • User.name == ‘tim‘
  • User.name != ‘tim‘
  • User.name.like(‘tim‘)
  • User.name.in_([‘tim‘, ‘White‘])
  • ~User.name.in_([‘tim‘, ‘white‘])
  • User.name == None or User.name.is_(None)
  • User.name != None or User.name.isnot(None)
  • from sqlalchemy import or_ /// filter(or_(expr1, expr2))
  • User.name.match(‘tim‘)
all(), one(), first()

Query 對象雖然是可迭代的,但對於多數確定需求的狀況,我們可能更希望直接把需要的資料取出來。

all() 和 first() 顧名思義,特別的是 one() 。

它較於 first() 多了一條約束,即Query 對象的結果集必須只包含一個對象,否則報錯,即:

session.query(User).filter(name==‘tim‘).one()

等價於:

foo = session.quert(User).filter(name=‘tim‘)assert len(foo.all()) == 1return foo.first()
SQL

在如 filter() 或 order_by() 這樣的方法中,條件運算式還可以是原始的 sql 語句,只需要用 text() 把語句包起來:

from sqlalchemy import textusers = session.query(User).filter(text(‘id<10‘)).order_by(text(‘id‘))

另一種更徹底的 sql 執行方式是使用 from_statement() 方法:

session.query(User).from_statement(text(‘SELECT * FROM user where id<10 and status=1‘)).all()

此時還可以直接 Query 列名:

>>> session.query(‘id‘, ‘name‘, ‘status‘).from_statement(‘SELECT * from user where class=3‘).all()>>> [(1, ‘jack‘, 0), (2, ‘rose‘, 1)]
counting

一種簡單的計數是對 Query 對象使用 count() 方法,用於返回 Query 對象的行數。

另一種較複雜的是 func.count(),它支援細分計數:

from sqlalchemy import funcsession.query(func.count(User.class), User.class).filter_by(User.class=‘a‘)session.query(func.count(User.class), User.class).group_by(User.class).all()
關係

略

SQLAlchemy ORM 參考

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.