我有一個使用Pyramid/SQLAlchemy/Postgresql構建的Web應用程序,它允許用戶管理一些數據,而且這些數據幾乎完全獨立於不同的用戶。說,愛麗絲訪問alice.domain.com
,並能夠上傳圖片和文件,鮑勃訪問bob.domain.com
,也能夠上傳圖片和文件。 Alice從來沒有看到任何由Bob創建的東西,反之亦然(這是一個簡化的例子,真的可能有很多數據在多個表中,但想法是相同的)。SQLAlchemy的多租戶
現在,最直接的選擇安排在數據庫後端的數據是使用一個單一的數據庫,其中每個表(pictures
和documents
)具有user_id
場,所以,基本上,讓所有Alice的照片,我可以做像
user_id = _figure_out_user_id_from_domain_name(request)
pictures = session.query(Picture).filter(Picture.user_id==user_id).all()
這是所有容易和簡單,但也有一些缺點
- 我需要記住進行查詢時,總是使用額外的過濾條件,否則愛麗絲可能會看到Bob的PI ctures;
- 如果有許多用戶表可能增長巨大
- 它可能很難拆分所以我想這將是非常好的每莫名其妙地分割數據多臺機器
之間的Web應用程序-用戶。我能想到的兩種方法:
同一個數據庫內單獨表爲Alice和Bob的圖片和文檔(Postgres的Schemas似乎是在這種情況下,使用正確的方法):
documents_alice documents_bob pictures_alice pictures_bob
,然後使用一些黑暗魔法,「路線」的所有查詢到一個或根據當前請求的域中的其它表:
_use_dark_magic_to_configure_sqlalchemy('alice.domain.com') pictures = session.query(Picture).all() # selects all Alice's pictures from "pictures_alice" table ... _use_dark_magic_to_configure_sqlalchemy('bob.domain.com') pictures = session.query(Picture).all() # selects all Bob's pictures from "pictures_bob" table
使用單獨的數據庫爲每個用戶:
- database_alice - pictures - documents - database_bob - pictures - documents
這似乎是最乾淨的解決方案,但我不知道如果有多個數據庫連接,將需要更多的內存和其他資源,限制可能的數字「租戶」。
所以,問題是,這一切都有意義嗎?如果是,我該如何配置SQLAlchemy以便在每個HTTP請求(對於選項1)上動態修改表名,或者維護到不同數據庫的連接池併爲每個請求使用正確的連接(對於選項2)?
密切相關:http://stackoverflow.com/questions/9298296/ sqlalchemy-support-postgres-schemas –
@CraigRinger:是的,如果從接受的答案中找到「SET search_path TO ...」thingie,那麼這就是選項#1的解決方案。謝謝。 – Sergey
如果你想避免將數據庫分割,那麼sqlalchemy.org上有一對關於[Pre-Filtered Queries](預過濾查詢)的食譜(http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PreFilteredQuery)和[全局過濾器](http://www.sqlalchemy.org/trac/wiki/UsageRecipes/GlobalFilter),可以幫助您避免不必要地拉取不希望的數據。 –