solana-bankingstage-dashboard/postgres_connection.py

73 lines
2.7 KiB
Python
Raw Normal View History

2023-10-18 00:20:38 -07:00
import pg8000
from dbutils.pooled_db import PooledDB
import ssl
import time
2023-10-18 00:20:38 -07:00
from os import environ
2023-11-30 05:53:56 -08:00
# keep default threadsafety
# If the underlying DB-API module is not thread-safe,
# thread locks will be used to ensure that the pooled_db connections are thread-safe.
# So you don't need to worry about that, but you should be careful to use dedicated
# connections whenever you change the database session or perform transactions spreading over more than one SQL command.
2023-11-30 05:53:56 -08:00
def _configure_sslcontext():
if environ.get('PGSSL', 'false') == 'true':
ssl_context = ssl.create_default_context()
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.check_hostname = False
ssl_context.load_verify_locations("ca.cer")
ssl_context.load_cert_chain("client.cer", keyfile="client-key.cer")
return ssl_context
else:
return None
# see https://webwareforpython.github.io/DBUtils/main.html#pooleddb-pooled-db
def _init_pool():
2023-11-30 22:38:38 -08:00
print("Setting up database connection pool...")
2023-11-30 05:55:39 -08:00
pool_size = int(environ.get('POOLED_DB_MAX_SIZE', '4'))
2023-11-30 05:53:56 -08:00
username = environ.get('PGUSER', 'mev_dashboard_query_user')
password = environ.get('PGPASSWORD')
assert password is not None, "PGPASSWORD environment variable must be set"
host = environ.get('PGHOST', 'localhost')
port = environ.get('PGPORT', '5432')
database = environ.get('PGDATABASE', 'mangolana')
ssl_context = _configure_sslcontext()
if ssl_context is not None:
print("... use SSL for database connection")
2023-11-30 05:53:56 -08:00
application_name = "bankingstage-dashboard"
timeout = 10
2023-12-01 05:00:40 -08:00
# note: for some unknown reason, database sees maxconnections+1 connections
the_pool = PooledDB(pg8000, maxconnections=pool_size, blocking=True, maxusage=100,
2023-11-30 22:38:38 -08:00
database=database, user=username, password=password, host=host, port=port,
application_name=application_name, timeout=timeout, ssl_context=ssl_context)
2023-11-30 05:53:56 -08:00
print("Initialized database connection pool with size ", pool_size)
2023-11-30 08:09:16 -08:00
return the_pool
2023-11-30 05:53:56 -08:00
pool = _init_pool()
2023-10-18 00:20:38 -07:00
2023-11-27 08:55:05 -08:00
2023-11-27 05:14:43 -08:00
def query(statement, args=[]):
start = time.time()
2023-11-30 05:53:56 -08:00
2023-11-27 05:14:43 -08:00
elapsed_connect = time.time() - start
2023-11-30 22:38:38 -08:00
with pool.connection() as db:
with db.cursor() as cursor:
try:
cursor.execute(statement, args=args)
elapsed_total = time.time() - start
keys = [k[0] for k in cursor.description]
maprows = [dict(zip(keys, row)) for row in cursor]
2023-11-30 22:38:38 -08:00
except Exception as ex:
print("Exception executing query:", ex)
return []
2023-11-27 08:18:57 -08:00
if elapsed_total > .2:
2023-11-27 05:14:43 -08:00
print("Database Query took", elapsed_total, "secs", "(", elapsed_connect, ")")
return maprows