我正在开发一个 SaaS 解决方案,目前在 kubernetes 上配置 sonarqube 和 gerrit 应用程序。
作为其中的一部分,我想在我的 postgres 数据库中为我提供的每个新应用程序创建一个新架构。应用程序正在使用以下连接字符串进行连接(即,instance1、instance2、instance3...等)
jdbc:postgresql://localhost/gerrit?user=instance1&password=instance1¤tSchema=instance1
通过在新模式中创建关联表,该解决方案对于首次出现的配置 gerrit 和 sonarqube 效果很好。但是,它在同一数据库中使用另一个新架构时第二次失败,这些失败很可能与应用程序尝试创建关联表但它已经存在有关。
我正在使用以下 sql 创建架构。
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;
我很难理解这种行为,针对同一数据库的两个不同模式配置的两个单独的应用程序如何能够看到彼此的表。
为了重现这个问题,我快速编写了一个 python 脚本来连接到同一数据库的两个不同模式并创建相同的表,它工作正常。
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 pg_test_connect.py
user: instance1
(1, 'tbl_1instance1')
$ python pg_test_connect.py
user: instance2
(1, 'tbl_1instance2')
既然我能够从 python 验证这个工作流程,这是否是 JDBC 或应用程序(gerrit 和 sonarqube)的限制,有人在使用 postgres 时遇到过这个问题吗?
最佳答案
默认的search_path是“$user”,公共(public)的。其中 $user 将替换为 SESSION_USER 的值,因此无需显式指定 ROLE 的 search_path。 但需要注意的是,用户必须对搜索路径中的任何模式拥有 USAGE 权限。如果“$user”模式不存在,它将被忽略。 (https://www.postgresql.org/docs/9.4/static/runtime-config-client.html)。
关于postgresql - 与同一 postgres 数据库的两个模式连接的应用程序的两个实例无法区分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44548111/