Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add execute_sql_rds.sh script to run SQL using RDS Data API #1847

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions api/bin/execute_sql_rds.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#!/usr/bin/env bash
#
# Execute some SQL using the RDS Data API.
#
# Examples:
# ./execute_sql_rds.sh <sql/table_list.sql
# ./execute_sql_rds.sh --cluster=api-prod --multiple <sql/select_from_foreign_table.sql
#
# When using --multiple, provide one SQL statement per input line.
#

set -o errexit -o pipefail

PROGRAM_NAME=$(basename "$0")

CYAN='\033[96m'
GREEN='\033[92m'
END='\033[0m'

CLUSTER=api-dev
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CLUSTER=api-dev
# Defaults the --cluster argument to api-dev
CLUSTER=api-dev


USAGE="Usage: $PROGRAM_NAME [OPTION]

--multiple one SQL statement per input line (otherwise expects a single multi-line statement)
--cluster=CLUSTER target RDS cluster (default $CLUSTER)
"


main() {
cluster="$CLUSTER"
parse_arguments "$@"
print_log "using cluster $cluster"
read_cluster_arns
create_temporary_directory

count=1
if [ $multiple ]
then
while read line
do
execute_statement "$line"
count=$((count + 1))
done
else
execute_statement "$(cat)"
fi
}


parse_arguments() {
for arg in "$@"
do
if [ "$arg" == "--multiple" ]; then
print_log "multiple mode enabled (one statement per input line)"
multiple=1
elif [[ "$arg" =~ ^--cluster=(.*)$ ]]; then
cluster="${BASH_REMATCH[1]}"
else
echo "$USAGE"
exit 1
fi
done
}


read_cluster_arns() {
resource_arn=$(aws rds describe-db-clusters --db-cluster-identifier="$cluster" \
--query='DBClusters[0].DBClusterArn' --output=text)
secret_arn=$(aws rds describe-db-clusters --db-cluster-identifier="$cluster" \
--query='DBClusters[0].MasterUserSecret.SecretArn' --output=text)
print_log "database resource $resource_arn"
}


create_temporary_directory() {
tmp_dir="/tmp/execute_sql_rds/execute_sql_rds.$(date +%s)"
mkdir -m "u=rwx,g=,o=" -p "$tmp_dir"
print_log "temporary directory $tmp_dir"
}


execute_statement() {
print_log "$1"
result_path="$tmp_dir/result_$count.json"

aws rds-data execute-statement \
--resource-arn "$resource_arn" \
--database "app" \
--secret-arn "$secret_arn" \
--sql "$1" \
--continue-after-timeout \
--format-records-as JSON \
>"$result_path"

if grep formattedRecords "$result_path" >/dev/null
then
jq -r .formattedRecords "$result_path" | jtbl --truncate --markdown
else
cat "$result_path"
fi
}


# Utility functions
print_log() {
printf "$CYAN%s $GREEN%s: $END%s\\n" "$(date "+%Y-%m-%d %H:%M:%S")" "$PROGRAM_NAME" "$*"
}

# Entry point
main "$@"
18 changes: 18 additions & 0 deletions api/bin/sql/select_from_foreign_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
SELECT * FROM legacy.tforecast ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tforecast_hist ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tapplicanttypes_forecast ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tapplicanttypes_forecast_hist ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tfundactcat_forecast ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tfundactcat_forecast_hist ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tfundinstr_forecast ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tfundinstr_forecast_hist ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.topportunity ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.topportunity_cfda ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tsynopsis ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tsynopsis_hist ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tapplicanttypes_synopsis ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tapplicanttypes_synopsis_hist ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tfundactcat_synopsis ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tfundactcat_synopsis_hist ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tfundinstr_synopsis ORDER BY created_date DESC LIMIT 8;
SELECT * FROM legacy.tfundinstr_synopsis_hist ORDER BY created_date DESC LIMIT 8;
15 changes: 15 additions & 0 deletions api/bin/sql/table_list.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
SELECT n.nspname as "Schema",
c.relname as "Name",
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END as "Type",
pg_catalog.pg_get_userbyid(c.relowner) as "Owner",
pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as "Size",
pg_stat_get_last_analyze_time(c.oid) AS last_analyze,
pg_stat_get_last_autoanalyze_time(c.oid) AS last_autoanalyze
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam
WHERE c.relkind IN ('r','f','v','m','')
AND n.nspname <> 'pg_catalog'
AND n.nspname !~ '^pg_toast'
AND n.nspname <> 'information_schema'
ORDER BY 1,2;
Loading