与同一postgres数据库的两个模式连接的应用程序的两个实例无法区分

时间:2017-06-14 14:50:09

标签: postgresql sonarqube multi-tenant gerrit saas

我正在开发 SaaS 解决方案,目前正在kubernetes上配置 sonarqube和gerrit 应用程序。

作为其中的一部分,我想在postgres数据库中为我提供的每个新应用程序创建一个新模式。应用程序使用以下连接字符串进行连接(即instance1,instance2,instance3 ......等等)

httpContext.Response.Body = stream;

通过在新架构中创建关联表,该解决方案适用于第一次配置gerrit和sonarqube。但是,它在同一数据库中第二次使用另一个新架构失败,这些失败很可能与尝试创建关联表的应用程序相关,但已经存在

我正在使用以下sql创建架构。

jdbc:postgresql://localhost/gerrit?user=instance1&password=instance1&currentSchema=instance1

我很难理解这种行为,如何针对同一数据库的两个不同模式配置的两个单独的应用程序可以看到彼此的表。

为了重现这个问题,我很快写了一个python脚本来连接到同一个数据库的两个不同模式并创建相同的表,它工作正常。

create user instance1 with login password 'instance1';
CREATE SCHEMA instance1 AUTHORIZATION instance1;
ALTER ROLE instance1 SET search_path=instance1;


create user instance2 with login password 'instance2';
CREATE SCHEMA instance2 AUTHORIZATION instance2;
ALTER ROLE instance2 SET search_path=instance2;

输出如下

import psycopg2
import sys
import random

_user = raw_input("user: ")
con = None

try:

   con = psycopg2.connect(database='gerrit', user=_user,
                           password=_user, host='localhost')
   cur = con.cursor()
   cur.execute('SELECT version()')
   ver = cur.fetchone()
   print ver
   table_name = 'tbl_%d' %(1)#random.randint(1,100))
   cur.execute('CREATE TABLE %s (id serial, name varchar(32));' %(table_name))
   cur.execute('INSERT INTO %s values (1, \'%s\');' %(table_name, table_name+_user))
   con.commit()
   cur.execute('SELECT * from %s' %(table_name))
   ver = cur.fetchone()
   print ver
except psycopg2.DatabaseError, e:
   print 'Error %s' % e
   sys.exit(1)
finally:
   if con:
       con.close()

由于我能够从python验证这个工作流程,这是来自 JDBC 还是应用程序(gerrit& sonarqube)的限制,有没有人遇到过postgres这个问题?

2 个答案:

答案 0 :(得分:1)

默认search_path是“$ user”,public。其中$ user将替换为SESSION_USER的值,因此不需要为ROLE显式指定search_path。 但需要注意的是,用户必须拥有搜索路径中任何架构的USAGE权限。如果“$ user”架构不存在,则将被忽略。 (https://www.postgresql.org/docs/9.4/static/runtime-config-client.html)。

答案 1 :(得分:1)

因此,在修改了gerrit源代码之后,我发现它没有兑现currentSchema选项。这或多或少地解释了为什么它一直这样做。