|
| 1 | +import os |
| 2 | +from collections.abc import Callable |
| 3 | + |
| 4 | +import psycopg |
| 5 | +import psycopg_pool |
| 6 | + |
| 7 | +from openslides_backend.shared.env import Environment |
| 8 | +from openslides_backend.shared.exceptions import DatabaseException |
| 9 | + |
| 10 | +env = Environment(os.environ) |
| 11 | +conn_string_without_db = f"host='{env.DATABASE_HOST}' port='{env.DATABASE_PORT}' user='{env.DATABASE_USER}' password='{env.PGPASSWORD}' " |
| 12 | +system_conn_pool = psycopg_pool.ConnectionPool( |
| 13 | + conninfo=conn_string_without_db + "dbname='postgres'", |
| 14 | + connection_class=psycopg.Connection, |
| 15 | + kwargs={"autocommit": True, "row_factory": psycopg.rows.dict_row}, |
| 16 | + min_size=1, |
| 17 | + max_size=1, |
| 18 | + open=True, |
| 19 | + check=psycopg_pool.ConnectionPool.check_connection, |
| 20 | + name="ConnPool for dev postgres", |
| 21 | + timeout=5.0, |
| 22 | + max_waiting=0, |
| 23 | + max_lifetime=3600.0, |
| 24 | + max_idle=600.0, |
| 25 | + reconnect_timeout=300.0, |
| 26 | + num_workers=1, |
| 27 | +) |
| 28 | +os_conn_pool = psycopg_pool.ConnectionPool( |
| 29 | + conninfo=conn_string_without_db + f"dbname='{env.DATABASE_NAME}'", |
| 30 | + connection_class=psycopg.Connection, |
| 31 | + kwargs={"autocommit": True, "row_factory": psycopg.rows.dict_row}, |
| 32 | + min_size=int(env.DB_POOL_MIN_SIZE), |
| 33 | + max_size=int(env.DB_POOL_MAX_SIZE), |
| 34 | + open=False, |
| 35 | + check=psycopg_pool.ConnectionPool.check_connection, |
| 36 | + name="ConnPool for openslides-db", |
| 37 | + timeout=float(env.DB_POOL_TIMEOUT), |
| 38 | + max_waiting=int(env.DB_POOL_MAX_WAITING), |
| 39 | + max_lifetime=float(env.DB_POOL_MAX_LIFETIME), |
| 40 | + max_idle=float(env.DB_POOL_MAX_IDLE), |
| 41 | + reconnect_timeout=float(env.DB_POOL_RECONNECT_TIMEOUT), |
| 42 | + num_workers=int(env.DB_POOL_NUM_WORKERS), |
| 43 | +) |
| 44 | + |
| 45 | + |
| 46 | +def get_unpooled_db_connection( |
| 47 | + db_name: str, |
| 48 | + autocommit: bool = False, |
| 49 | + row_factory: Callable = psycopg.rows.dict_row, |
| 50 | +) -> psycopg.Connection: |
| 51 | + """Use for temporary connections, where pooling is not helpfull like tests and other specific DDL-Connections""" |
| 52 | + try: |
| 53 | + db_connection = psycopg.connect( |
| 54 | + f"host='{env.DATABASE_HOST}' port='{env.DATABASE_PORT}' dbname='{db_name}' user='{env.DATABASE_USER}' password='{env.PGPASSWORD}'", |
| 55 | + autocommit=autocommit, |
| 56 | + row_factory=row_factory, |
| 57 | + ) |
| 58 | + db_connection.isolation_level = psycopg.IsolationLevel.SERIALIZABLE |
| 59 | + except psycopg.OperationalError as e: |
| 60 | + raise DatabaseException(f"Cannot connect to postgres: {str(e)}") |
| 61 | + return db_connection |
0 commit comments