2013-04-29 50 views
2

編輯:主題: 有沒有一種方法可以強制SqlAlchemy預填充會話儘可能?從數據庫儘可能多地同步狀態(此時不會有數據庫更新)。SqlAlchemy預讀緩存?

我有一些溫和的性能問題,我相信我已將它追溯到SqlAlchemy。我確信我的聲明和db-schema中有可以改善時間的變化,但這不是我在這裏問的。我的SqlAlchemy聲明定義了8個類,我的數據庫有11個表,其中只有7個表擁有我的真實數據,總共我的數據庫有800個記錄(所有Integers和UnicodeText)。我的數據庫引擎是sqlite,實際大小目前是242Kb。

真的,實體的數量非常小,但許多表關係具有遞歸行爲(5-6級深)。我的問題始於SA爲我做的美妙的automagic,並且我不願意用我自己的python類正確提取數據。

我有ORM屬性訪問分散在各種迭代器,遞歸評估器,直到我的文件I/O流。對這些屬性的訪問基本上是非線性的,有時我會查找,我的調用堆棧在SqlAlchemy中消失了很長一段時間,並且我得到了很多單例查詢。

我使用的主要是默認的SA設置(python 2.7.2,sqlalchemy 0.7)。

考慮到RAM不是問題,而且我的數據庫很小(暫時),有沒有一種方法可以強制SqlAlchemy儘可能地預先填充會話。我希望如果我只是將原始數據加載到內存中,那麼我最需要做的就是動態追加一些連接(幾乎所有查詢都很直接)。

我希望有5分鐘的修復時間,以便儘快運行一些報告。我的TODO的下個月可能會充滿直接表查詢和更緊密的業務邏輯,可以管理元組。

+0

你的問題過於冗長,你的問題到底是什麼? – Wessie 2013-04-29 13:31:47

+0

這聽起來像你想像一個數據庫一樣使用SqlAlchemy,而不是像一個ORM。 – 2013-04-29 17:30:31

+0

我不能只是查詢表(或實際上,這是否會工作,我想要?),它的ORM位,我掛了。我有很多多態性和我所依賴的關係。 – user2097818 2013-04-29 17:42:04

回答

1

針對這類問題的五分鐘修復是不太可能的,但對於多對一的「單身人士」來說,我經常使用一個簡單的配方。假設你正在加載大量User的對象,他們都有某種的Category多到一個參考:

# load all categories, then hold onto them 
categories = Session.query(Category).all() 

for user in Session.query(User): 
    print user, user.category # no SQL will be emitted for the Category 

這是因爲query.get()一個多到一個發射將看在本地第一個主鍵的身份映射。

如果您正在尋找比此更多的緩存(並且有超過五分鐘的備用空間),則可以擴展相同的概念以緩存SELECT語句的結果,以便僅緩存關聯與當前會話 - 查看分發示例中包含的local_session_caching.py配方。

+0

我有查詢結果後是否需要實際嘗試訪問屬性?如果我直接查詢表,這些列值保存在內存中用於ORM查詢? – user2097818 2013-04-29 22:27:15

+0

當Query發出一個SELECT時,它總是發出它,並且總是獲取所有行 - 那麼大多數DBAPI將最終獲得那些行中的所有列,即使它們沒有被讀取。然後它將這些行匹配到已經加載到Session中的對象,並丟棄那些已經有對象的對象。因此,除非在該示例中進行查詢緩存,否則查詢始終會發出SQL,但使用query.get()並且身份已存在的情況除外。 – zzzeek 2013-04-30 04:03:30

+0

我最初沒有提到我的聲明部分是使用Elixir定義的(我正在進行遷移),也許這是我的一些問題。以你建議的形式執行查詢肯定有幫助。 – user2097818 2013-05-03 15:40:58