Skip to content

Commit 9604795

Browse files
kweinmeisteraverikitsch
authored andcommitted
chore: migrate run/idp-sql to sqlalchemy 2 (#9121)
* chore: migrate run/idp-sql to sqlalchemy 2 * linting * temp remove cleanup for debugging * switch to db.begin() for commits * remove cleanup for debugging * fix index parameters * add back cleanup --------- Co-authored-by: Averi Kitsch <[email protected]>
1 parent fc9f776 commit 9604795

File tree

3 files changed

+21
-25
lines changed

3 files changed

+21
-25
lines changed

run/idp-sql/README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,20 @@ connection.
6363

6464
[Instructions to launch proxy with TCP](https://github.com/GoogleCloudPlatform/python-docs-samples/tree/main/cloud-sql/postgres/sqlalchemy#launch-proxy-with-tcp)
6565

66-
6766
## Testing
6867

6968
Tests expect the Cloud SQL instance to already be created and environment Variables
7069
to be set.
7170

7271
### Unit tests
7372

74-
```
73+
```sh
7574
pytest test_app.py
7675
```
7776

7877
### System Tests
7978

80-
```
79+
```sh
8180
export GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
8281
export CLOUD_SQL_CONNECTION_NAME=<YOUR_CLOUD_SQL_CONNECTION_NAME>
8382
export DB_PASSWORD=<POSTGRESQL_PASSWORD>

run/idp-sql/database.py

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
import datetime
1616
import os
17-
from typing import Dict
17+
from typing import Any, Dict, Type
1818

1919
import sqlalchemy
2020
from sqlalchemy.orm import close_all_sessions
@@ -30,12 +30,12 @@
3030
db = None
3131

3232

33-
def init_connection_engine() -> Dict[str, int]:
33+
def init_connection_engine() -> sqlalchemy.engine.base.Engine:
3434
if os.getenv("TRAMPOLINE_CI", None):
3535
logger.info("Using NullPool for testing")
36-
db_config = {"poolclass": NullPool}
36+
db_config: Dict[str, Any] = {"poolclass": NullPool}
3737
else:
38-
db_config = {
38+
db_config: Dict[str, Any] = {
3939
# Pool size is the maximum number of permanent connections to keep.
4040
"pool_size": 5,
4141
# Temporarily exceeds the set pool_size if no connections are available.
@@ -61,7 +61,7 @@ def init_connection_engine() -> Dict[str, int]:
6161

6262

6363
def init_tcp_connection_engine(
64-
db_config: Dict[str, str]
64+
db_config: Dict[str, Type[NullPool]]
6565
) -> sqlalchemy.engine.base.Engine:
6666
creds = credentials.get_cred_config()
6767
db_user = creds["DB_USER"]
@@ -94,7 +94,7 @@ def init_tcp_connection_engine(
9494

9595
# [START cloudrun_user_auth_sql_connect]
9696
def init_unix_connection_engine(
97-
db_config: Dict[str, str]
97+
db_config: Dict[str, int]
9898
) -> sqlalchemy.engine.base.Engine:
9999
creds = credentials.get_cred_config()
100100
db_user = creds["DB_USER"]
@@ -113,9 +113,8 @@ def init_unix_connection_engine(
113113
password=db_pass, # e.g. "my-database-password"
114114
database=db_name, # e.g. "my-database-name"
115115
query={
116-
"unix_sock": "{}/{}/.s.PGSQL.5432".format(
117-
db_socket_dir, cloud_sql_connection_name # e.g. "/cloudsql"
118-
) # i.e "<PROJECT-NAME>:<INSTANCE-REGION>:<INSTANCE-NAME>"
116+
"unix_sock": f"{db_socket_dir}/{cloud_sql_connection_name}/.s.PGSQL.5432"
117+
# e.g. "/cloudsql", "<PROJECT-NAME>:<INSTANCE-REGION>:<INSTANCE-NAME>"
119118
},
120119
),
121120
**db_config,
@@ -136,26 +135,26 @@ def create_tables() -> None:
136135
global db
137136
db = init_connection_engine()
138137
# Create pet_votes table if it doesn't already exist
139-
with db.connect() as conn:
140-
conn.execute(
138+
with db.begin() as conn:
139+
conn.execute(sqlalchemy.text(
141140
"CREATE TABLE IF NOT EXISTS pet_votes"
142141
"( vote_id SERIAL NOT NULL, "
143142
"time_cast timestamp NOT NULL, "
144143
"candidate VARCHAR(6) NOT NULL, "
145144
"uid VARCHAR(128) NOT NULL, "
146145
"PRIMARY KEY (vote_id)"
147146
");"
148-
)
147+
))
149148

150149

151-
def get_index_context() -> Dict:
150+
def get_index_context() -> Dict[str, Any]:
152151
votes = []
153152
with db.connect() as conn:
154153
# Execute the query and fetch all results
155-
recent_votes = conn.execute(
154+
recent_votes = conn.execute(sqlalchemy.text(
156155
"SELECT candidate, time_cast FROM pet_votes "
157156
"ORDER BY time_cast DESC LIMIT 5"
158-
).fetchall()
157+
)).fetchall()
159158
# Convert the results into a list of dicts representing votes
160159
for row in recent_votes:
161160
votes.append(
@@ -168,11 +167,9 @@ def get_index_context() -> Dict:
168167
"SELECT COUNT(vote_id) FROM pet_votes WHERE candidate=:candidate"
169168
)
170169
# Count number of votes for cats
171-
cats_result = conn.execute(stmt, candidate="CATS").fetchone()
172-
cats_count = cats_result[0]
170+
cats_count = conn.execute(stmt, parameters={"candidate": "CATS"}).scalar()
173171
# Count number of votes for dogs
174-
dogs_result = conn.execute(stmt, candidate="DOGS").fetchone()
175-
dogs_count = dogs_result[0]
172+
dogs_count = conn.execute(stmt, parameters={"candidate": "DOGS"}).scalar()
176173
return {
177174
"dogs_count": dogs_count,
178175
"recent_votes": votes,
@@ -189,8 +186,8 @@ def save_vote(team: str, uid: str, time_cast: datetime.datetime) -> None:
189186

190187
# Using a with statement ensures that the connection is always released
191188
# back into the pool at the end of statement (even if an error occurs)
192-
with db.connect() as conn:
193-
conn.execute(stmt, time_cast=time_cast, candidate=team, uid=uid)
189+
with db.begin() as conn:
190+
conn.execute(stmt, parameters={"time_cast": time_cast, "candidate": team, "uid": uid})
194191
logger.info("Vote for %s saved.", team)
195192

196193

run/idp-sql/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Flask==2.1.0
2-
SQLAlchemy==1.4.38
2+
SQLAlchemy==2.0.3
33
pg8000==1.24.2
44
gunicorn==20.1.0
55
firebase-admin==6.0.0

0 commit comments

Comments
 (0)