我们的系统运行在Ubuntu, python 3.4,postgres 9.4.x和psycopg2上.
我们(将在未来)使用模式在dev,test和prod环境之间进行分割.我创建了一种方便的方法来创建与数据库的连接.它使用json连接配置文件来创建连接字符串.我想配置连接以使用返回的连接为所有后续查询使用特定模式.我不希望我的查询有硬编码模式,因为我们应该能够轻松地在它们之间切换,具体取决于我们是处于开发,测试还是生产阶段/环境.
目前,便捷方法如下所示:
def connect(conn_config_file = 'Commons/config/conn_commons.json'): with open(conn_config_file) as config_file: conn_config = json.load(config_file) conn = psycopg2.connect( "dbname='" + conn_config['dbname'] + "' " + "user='" + conn_config['user'] + "' " + "host='" + conn_config['host'] + "' " + "password='" + conn_config['password'] + "' " + "port=" + conn_config['port'] + " " ) cur = conn.cursor() cur.execute("SET search_path TO " + conn_config['schema']) return conn
只要你给它时间来执行set search_path查询,它就可以正常工作.不幸的是,如果我执行以下查询的速度太快,则会在未设置search_path的情况下发生竞争条件.我试图在返回conn之前强制执行conn.commit(),但是,这会将search_path重置为默认的架构postgres,以便它不会使用,比如prod.在数据库或应用程序层的建议是可取的,但是,我知道我们可能也可以在操作系统级别解决这个问题,也欢迎在这方面提出任何建议.
示例json配置文件如下所示:
{ "dbname": "thedatabase", "user": "theuser", "host": "localhost", "password": "theusers_secret_password", "port": "6432", "schema": "prod" }
任何建议都非常感谢.
我认为更好的想法是使用像DatabaseCursor这样的东西返回游标,用于执行带有“SET search_path …”而不是连接的查询.
我的意思是这样的:
class DatabaseCursor(object): def __init__(self, conn_config_file): with open(conn_config_file) as config_file: self.conn_config = json.load(config_file) def __enter__(self): self.conn = psycopg2.connect( "dbname='" + self.conn_config['dbname'] + "' " + "user='" + self.conn_config['user'] + "' " + "host='" + self.conn_config['host'] + "' " + "password='" + self.conn_config['password'] + "' " + "port=" + self.conn_config['port'] + " " ) self.cur = self.conn.cursor() self.cur.execute("SET search_path TO " + self.conn_config['schema']) return self.cur def __exit__(self, exc_type, exc_val, exc_tb): # some logic to commit/rollback self.conn.close()
和
with DatabaseCursor('Commons/config/conn_commons.json') as cur: cur.execute("...")