-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathredshift_api.py
More file actions
114 lines (94 loc) · 3.24 KB
/
Copy pathredshift_api.py
File metadata and controls
114 lines (94 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
"""
Redshift engine compatible with streamlit cache
"""
from functools import lru_cache
from typing import Callable
import streamlit as st
from dotenv import load_dotenv
import sqlalchemy as sa
from sqlalchemy import text
from sqlalchemy.engine.url import URL
load_dotenv('.env.local')
import os
# Redshift connection parameters from environment
REDSHIFT_USER = os.getenv("REDSHIFT_USER")
REDSHIFT_PASSWORD = os.getenv("REDSHIFT_PASSWORD")
REDSHIFT_HOST = os.getenv("REDSHIFT_HOST")
def _create_engine():
# build the sqlalchemy URL
url = URL.create(
drivername="postgresql+psycopg2",
# drivername='redshift+redshift_connector', # indicate redshift_connector driver and dialect will be used
# drivername="redshift+psycopg2",
host=REDSHIFT_HOST, # Amazon Redshift host
port=5439, # Amazon Redshift port
database='report', # Amazon Redshift database
username=REDSHIFT_USER, # Amazon Redshift username
password=REDSHIFT_PASSWORD # Amazon Redshift password
)
engine = sa.create_engine(url,
pool_pre_ping=True, # ✅ Goes here
pool_recycle=3600, # Recycle connections after 1 hour
pool_size=5,
max_overflow=10)
sql = """
SELECT id FROM aha_report_v5.fact_answers2 LIMIT 1;
"""
with engine.connect() as conn:
conn.execute(text(sql))
return engine
import arrow
def _execute(sql, create_engine: Callable):
now = arrow.now()
engine = create_engine()
print(f'\nEngine time: {arrow.now() - now}')
now = arrow.now()
with engine.connect() as conn:
print(f'\nConnection time: {arrow.now() - now}')
now = arrow.now()
print(f'\nSQL: {text(sql)}')
res = conn.execute(text(sql))
rows = res.fetchall()
print(f'\nFetching time: {arrow.now() - now}')
return rows
@st.cache_resource(ttl='60m')
def st_create_engine():
return _create_engine()
def _pure_execute(sql, create_engine: Callable):
now = arrow.now()
engine = create_engine()
print(f'\nEngine time: {arrow.now() - now}')
now = arrow.now()
with engine.connect() as conn:
print(f'\nConnection time: {arrow.now() - now}')
now = arrow.now()
print(f'\nSQL: {text(sql)}')
res = conn.execute(text(sql))
print(f'\nResult: {res}, Fetching time: {arrow.now() - now}')
return None
@st.cache_data(ttl='60m')
def pure_execute(sql):
return _pure_execute(sql, st_create_engine)
@st.cache_data(ttl='60m')
def execute(sql):
return _execute(sql, st_create_engine)
def _execute_with_columns(sql, create_engine: Callable):
engine = create_engine()
with engine.connect() as conn:
res = conn.execute(text(sql))
rows = res.fetchall()
cols = res.keys()
return rows, cols
@lru_cache(maxsize=100)
def execute_with_columns(sql):
print(f'Execute_with_columns: {sql}')
now = arrow.now()
rows, cols = _execute_with_columns(sql, _create_engine)
print(f'{len(rows)} rows in {arrow.now() - now}')
return rows, cols
@st.cache_resource(ttl='60m')
def st_execute_with_columns(sql):
now = arrow.now()
rows, cols = _execute_with_columns(sql, _create_engine)
print(f'{len(rows)} rows in {arrow.now() - now}')
return rows, cols