Skip to content

Commit 3683def

Browse files
committed
Implement execute_values to make SR upload fast
1 parent cfbac32 commit 3683def

2 files changed

Lines changed: 39 additions & 37 deletions

File tree

app/airflow/dags/libs/SR_processing/db_services.py

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55
from airflow.providers.postgres.hooks.postgres import PostgresHook
66
from libs.enums import JobStageType, StageStatusType
77
from libs.queries import create_fields_query
8-
from libs.settings import AIRFLOW_DAGRUN_TIMEOUT, AIRFLOW_DEBUG_MODE
8+
from libs.settings import (
9+
AIRFLOW_DAGRUN_TIMEOUT,
10+
AIRFLOW_DEBUG_MODE,
11+
EXECUTE_VALUES_PAGE_SIZE,
12+
)
913
from libs.utils import update_job_status
1014
from openpyxl.worksheet.worksheet import Worksheet
15+
from psycopg2.extras import execute_values
1116

1217
# PostgreSQL connection hook
1318
pg_hook = PostgresHook(
@@ -107,26 +112,26 @@ def update_temp_data_dictionary_table(
107112

108113
# Insert records into the temporary table
109114
if dictionary_records:
110-
pg_hook.insert_rows(
111-
table=f"temp_data_dictionary_{scan_report_id}",
112-
rows=[
113-
(
114-
d["table_name"],
115-
d["field_name"],
116-
d["value"],
117-
d["value_description"],
115+
# Get a database connection - this automatically commits on success or rolls back on error
116+
with pg_hook.get_conn() as conn:
117+
# Create a cursor for executing SQL - this automatically closes when we're done
118+
with conn.cursor() as cursor:
119+
# Bulk insert all records efficiently using execute_values
120+
execute_values(
121+
cursor,
122+
f"INSERT INTO temp_data_dictionary_{scan_report_id} (table_name, field_name, value, value_description) VALUES %s",
123+
[
124+
(
125+
d["table_name"],
126+
d["field_name"],
127+
d["value"],
128+
d["value_description"],
129+
)
130+
for d in dictionary_records
131+
],
132+
page_size=EXECUTE_VALUES_PAGE_SIZE,
118133
)
119-
for d in dictionary_records
120-
],
121-
target_fields=[
122-
"table_name",
123-
"field_name",
124-
"value",
125-
"value_description",
126-
],
127-
fast_executemany=True,
128-
commit_every=10000, # commit every 10k
129-
)
134+
conn.commit()
130135

131136
logging.info(
132137
f"Created temporary data dictionary table with {len(dictionary_records)} records"
@@ -198,24 +203,18 @@ def create_temp_field_values_table(
198203
)
199204

200205
if field_values_data:
201-
pg_hook.insert_rows(
202-
table=f"temp_field_values_{table_id}",
203-
rows=[
204-
(
205-
d["field_name"],
206-
d["value"],
207-
d["frequency"],
206+
with pg_hook.get_conn() as conn:
207+
with conn.cursor() as cursor:
208+
execute_values(
209+
cursor,
210+
f"INSERT INTO temp_field_values_{table_id} (field_name, value, frequency) VALUES %s",
211+
[
212+
(d["field_name"], d["value"], d["frequency"])
213+
for d in field_values_data
214+
],
215+
page_size=EXECUTE_VALUES_PAGE_SIZE,
208216
)
209-
for d in field_values_data
210-
],
211-
target_fields=[
212-
"field_name",
213-
"value",
214-
"frequency",
215-
],
216-
fast_executemany=True,
217-
commit_every=10000, # commit every 10k
218-
)
217+
conn.commit()
219218

220219
except Exception as e:
221220
logging.error(f"Error creating data dictionary table: {str(e)}")

app/airflow/dags/libs/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,7 @@
1717
# Timedelta for dagrun_timeout in minutes
1818
AIRFLOW_DAGRUN_TIMEOUT = os.getenv("AIRFLOW_DAGRUN_TIMEOUT", 60)
1919

20+
# Page size for bulk database inserts (execute_values)
21+
EXECUTE_VALUES_PAGE_SIZE = int(os.getenv("EXECUTE_VALUES_PAGE_SIZE", 100))
22+
2023
AIRFLOW_VAR_JSON_VERSION = os.getenv("AIRFLOW_VAR_JSON_VERSION", "v1")

0 commit comments

Comments
 (0)