Два экземпляра приложения, связанные с двумя схемами одной и той же базы данных postgres, не могут различать

Я работаю над решением SaaS, в настоящее время обеспечивающим приложения sonarqube и gerrit на кубернетах.

В рамках этого я хочу создать новую схему в моей базе данных postgres для каждого нового приложения, которое я предоставляю. Приложение подключается с использованием следующей строки подключения (например, instance1, instance2, instance3 ... и т. Д.)

jdbc:postgresql://localhost/gerrit?user=instance1&password=instance1&currentSchema=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?


person Raghavendra Pathi    schedule 14.06.2017    source источник
comment
На стороне postgres вы можете увеличить ведение журнала (регистрировать все операторы), чтобы увидеть, что эти искалеченные ORM пытаются делать. Также: я бы добавил pg_catalog в search_paths. (а может и публично)   -  person wildplasser    schedule 14.06.2017


Ответы (2)


По умолчанию search_path - "$ user", общедоступный. Где $ user будет заменен значением SESSION_USER, поэтому нет необходимости явно указывать search_path для РОЛИ. Но предостережение заключается в том, что у пользователя должно быть разрешение на ИСПОЛЬЗОВАНИЕ любой схемы в пределах пути поиска. Если схема «$ user» не существует, она будет проигнорирована. (https://www.postgresql.org/docs/9.4/static/runtime-config-client.html).

person Alex Skorohod    schedule 19.06.2017

Итак, поработав исходный код gerrit, я понял, что он не учитывает параметр currentSchema. Это более или менее объясняет, почему он так себя ведет.

person Raghavendra Pathi    schedule 20.06.2017