为了账号安全,请及时绑定邮箱和手机立即绑定

Postgres模式的SQLAlchemy支持

Postgres模式的SQLAlchemy支持

有只小跳蛙 2019-12-25 15:57:04
我们使用SQLAlchemy和postgres托管一个多租户应用程序。我正在考虑从为每个租户使用单独的数据库迁移到具有多个架构的单个数据库。SQLAlchemy是否原生支持此功能?我基本上只是希望每个查询都以预定的模式作为前缀...例如select * from client1.users而不只是select * from users请注意,我想为特定请求/一组请求中的所有表切换架构,而不仅仅是在这里和那里的单个表。我想这也可以通过自定义查询类来完成,但是我无法想象在这方面还没有做任何事情。
查看完整描述

3 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

如果要在连接字符串级别执行此操作,请使用以下命令:


dbschema='schema1,schema2,public' # Searches left-to-right

engine = create_engine(

    'postgresql+psycopg2://dbuser@dbhost:5432/dbname',

    connect_args={'options': '-csearch_path={}'.format(dbschema)})

但是,对于多客户端(多租户)应用程序,更好的解决方案是为每个客户端配置一个不同的db用户,并为每个用户配置相关的search_path:


alter role user1 set search_path = "$user", public


查看完整回答
反对 回复 2019-12-25
?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

您可能可以使用sqlalchemy事件界面进行管理。因此,在创建第一个连接之前,请按照以下步骤设置一个侦听器:


from sqlalchemy import event

from sqlalchemy.pool import Pool


def set_search_path( db_conn, conn_proxy ):

    print "Setting search path..."

    db_conn.cursor().execute('set search_path=client9, public')


event.listen(Pool,'connect', set_search_path )

显然,这需要在创建第一个连接之前执行(例如,在应用程序初始化中)


我在session.execute(...)解决方案中看到的问题是,它在会话使用的特定连接上执行。但是,我在sqlalchemy中看不到任何可以保证会话将无限期继续使用相同连接的东西。如果它从连接池中拾取新连接,则它将丢失搜索路径设置。


我需要这样一种方法来设置应用程序search_path,它与数据库或用户搜索路径不同。我希望能够在引擎配置中进行设置,但是看不到一种实现方法。使用connect事件确实有效。如果有人有一个更简单的解决方案,我将感兴趣。


另一方面,如果您想在一个应用程序中处理多个客户端,则此方法将不起作用-我猜session.execute(...)方法可能是最好的方法。


查看完整回答
反对 回复 2019-12-25
  • 3 回答
  • 0 关注
  • 1084 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信