postgresql - SQLAlchemy 对 Postgres 模式的支持

标签 postgresql sqlalchemy

我们使用 SQLAlchemy 和 postgres 托管一个 Multi-Tenancy 应用程序。我正在考虑从为每个租户拥有单独的数据库转变为具有多个模式的单一数据库。 SQLAlchemy 本身支持这个吗?我基本上只希望每个查询都以预先确定的模式为前缀......例如

select * from client1.users

不仅仅是

select * from users

请注意,我想为特定请求/一组请求中的所有表切换架构,而不仅仅是各处的单个表。

我想这也可以通过自定义查询类来完成,但我无法想象还没有以这种方式完成的事情。

最佳答案

好吧,有几种方法可以做到这一点,这取决于您的应用程序的结构。这是最基本的方法:

meta = MetaData(schema="client1")

如果您的应用程序在整个应用程序中一次运行一个“客户端”,那么您就完成了。

但这里可能有问题的是,该元数据中的每个表都在该架构上。如果您希望一个应用程序同时支持多个客户端(通常是“ Multi-Tenancy ”的意思),这将很笨拙,因为您需要创建元数据的副本并为每个客户端复制所有映射。如果您真的愿意,可以使用这种方法,它的工作方式是您使用特定的映射类访问每个客户端,例如:

client1_foo = Client1Foo()

在这种情况下,您将使用 http://www.sqlalchemy.org/trac/wiki/UsageRecipes/EntityName 处的“实体名称”配方结合 sometable.tometadata()(参见 http://docs.sqlalchemy.org/en/latest/core/metadata.html#sqlalchemy.schema.Table.tometadata)。

那么假设它真正工作的方式是在应用程序中有多个客户端,但每个线程一次只有一个。实际上,在 Postgresql 中最简单的方法是在开始使用连接时设置搜索路径:

# start request

# new session
sess = Session()

# set the search path
sess.execute("SET search_path TO client1")

# do stuff with session

# close it.  if you're using connection pooling, the
# search path is still set up there, so you might want to 
# revert it first
sess.close()

最后一种方法是使用@compiles 扩展来覆盖编译器,以将“模式”名称粘贴在语句中。这是可行的,但会很棘手,因为对于生成“Table”的所有地方都没有一致的钩子(Hook)。您最好的选择可能是为每个请求设置搜索路径。

关于postgresql - SQLAlchemy 对 Postgres 模式的支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9298296/

相关文章:

postgresql - TO_CHAR PostgreSQL

sql - PostgreSQL - 选择不存在特定列的表

python - SqlAlchemy:将日期时间列转换为日期列

sql - 使用 SQLAlchemy 过滤 sql count(*)

postgresql - CSV 文件数据到 PostgreSQL 表中

python - Django/PostgreSQL 全文搜索 - 在 AWS RDS PostgreSQL 上使用 SearchVector 与 SearchVectorField 时的不同搜索结果

sql - Postgresql:检查模式是否存在?

python - 无法初始化 Elixir

python - SQLAlchemy 自动映射没有主键的 MSSQL View

python - 如何使用 sqlalchemy 打印 CreateTable(table)