關於ORM,以及Python中SQLAlchemy的sessionmaker,scoped_session
orm(object relational mapping):對象關系映射。
python面向對象,而數據庫是關系型。
orm是將數據庫關系映射為Python中的對象,不用直接寫SQL。
缺點是性能略差。
通過sessionmaker,我們得到一個類,一個能產生session的工廠。
我們可以用這個類的對象來操作數據庫。example:
from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # an Engine, which the Session will use for connection # resources some_engine = create_engine(‘postgresql://scott:tiger@localhost/‘) # create a configured "Session" class Session = sessionmaker(bind=some_engine) # create a Session session = Session() # work with sess myobject = MyObject(‘foo‘, ‘bar‘) session.add(myobject) session.commit()
然而,此時如果我們再創建一個Session對象的時候,新的對象和原來的對象是不同的:
...... >>> session1 = Session() >>> session2 = Session() >>> session1 is session2 False
而使用scoped_session的目的主要是為了線程安全。
scoped_session類似單例模式,當我們調用使用的時候,會先在Registry裏找找之前是否已經創建session了。
要是有,就把這個session返回。
要是沒有,就創建新的session,註冊到Registry中以便下次返回給調用者。
這樣就實現了這樣一個目的:在同一個線程中,call scoped_session 的時候,返回的是同一個對象:
>>> from sqlalchemy.orm import scoped_session >>> from sqlalchemy.orm import sessionmaker >>> session_factory = sessionmaker(bind=some_engine) >>> Session = scoped_session(session_factory) >>> some_session = Session() >>> some_other_session = Session() >>> some_session is some_other_session True
scoped_session實現了代理模式。能夠將操作轉發到代理的對象中去執行:
Session = scoped_session(some_factory) # equivalent to: # # session = Session() # print(session.query(MyClass).all()) # print(Session.query(MyClass).all())
scoped_session的實現使用了thread local storage技術,使session實現了線程隔離。這樣我們就只能看見本線程的session。
ref:http://docs.sqlalchemy.org/en/latest/orm/contextual.html#unitofwork-contextual
https://farer.org/2017/10/28/sqlalchemy_scoped_session/
http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#session-faq-whentocreate
http://hshsh.me/post/2016-04-10-python-proxy-class-examples/
關於ORM,以及Python中SQLAlchemy的sessionmaker,scoped_session