Requirement : Check if an UPDATE was run on a Redshift Table and Send SMS Programmatically using Amazon SNS. This script can be used in a variety of different scenarios, for eg: you can use the same logic to check for load errors on you cluster or check for INSERTS or DELETE commands.
Check if an UPDATE has occurred on a Table and send an SMS everytime the table is updated
Pre-requisites :
1. BOTO3 Python SDK installed for Python3.7
2. AWS CLI installed
3. Pscyopg2 package installed for Python3.7
4. Redshift Cluster
5. Amazon SNS configured to send SMS
6. Basic understanding of Python scripting, BOTO3 and Redshift.
Environment:
EC2 Instance Running CENTOS
Python3.7 Installed
AWS CLI installed and Configured Account credentials
Solution:
We will create a Python script to check svl_statementtext for update statements on a table ‘TEST’. The script can be configured to run in crontab every minute and if it an UPDATE occurs it dispatches an SMS using SNS.
1. Create the TEST table in your Redshift cluster and Insert some data into it
testdb=# create table test (id int8, name varchar(20));
CREATE TABLE
testdb=# insert into test values(1,’John’);
INSERT 0 1
testdb=# insert into test values(2,’Matt’);
INSERT 0 1
testdb=# insert into test values(3,’Chris’);
2. Run an UPDATE statement on the table and check svl_statementtext
testdb=# select * from test;
id | name
—-+——-
1 | John
2 | Matt
3 | Chris
(3 rows)
testdb=# update test set name=’Tim’ where id=1;
UPDATE 1
testdb=# select * from svl_statementtext where text ilike ‘update%test%’ and starttime > date_trunc(‘minute’, sysdate);
userid | xid | pid | label | starttime
| endtime | sequence | type |
text
100 | 506858 | 20017 | default | 2019-05-25 14:44:41.
657139 | 2019-05-25 14:44:49.955101 | 0 | QUERY | update test set name=’T
im’ where id=1;
(1 row)
As you can see the table logs the update command and displays it. Now we will run another update command and check the same table but using count(*)
testdb=# update test set name=’John’ where id=1;
UPDATE 1
testdb=#
select count(*) from svl_statementtext where text ilike ‘update%test%’
and starttime > date_trunc(‘minute’, sysdate);
count
——-
1
(1 row)
So it correctly display that 1 row was updated in the last minute on table ‘TEST’. Using this logic we can poll the table every minute to see if a transaction hit the table svl_statementtext. And if it did we will send an SMS via SNS
3. Python Script (#Attached svl_statementtext_1min.py) to Check for UPDATE statements in last one minute and if COUNT is not ‘0’ then send an SMS
import boto3
import psycopg2
#Obtaining the connection to RedShift
con=psycopg2.connect(dbname= ‘testdb’, host=’redshift-dc2-test.ctzrqaulg0u6.us-east-1.redshift.amazonaws.com’,
port= ‘5439’, user= ‘awsuser’, password= ‘********’)
#Opening a cursor and run sql query
cur = con.cursor()
cur.execute(“select
count(*) from svl_statementtext where text ilike ‘update%test%’ and
starttime > date_trunc(‘minute’, sysdate);”)
data = str(cur.fetchone())
print(data)
con.commit()
#Close the cursor and the connection
cur.close()
con.close()
# Compare data variable for threshold
if data == ‘(0,)’:
print(“NO UPDATES IN LAST 1 MINUTE ON TABLE TEST”)
else:
print(“UPDATES IN LAST 1 MINUTE ON TABLE TEST”)
# Create an SNS client
client = boto3.client(
“sns”,”us-east-1″
)
# Create the topic if it doesn’t exist
topic = client.create_topic(Name=”invites-for-push-notifications”)
topic_arn = topic[‘TopicArn’] # get its Amazon Resource Name
# Get List of Contacts
list_of_contacts = [“+6144*********”] # <– You can add a list of mutiple mobile numbers here
# Add SMS Subscribers
for number in list_of_contacts:
client.subscribe(
TopicArn=topic_arn,
Protocol=’sms’,
Endpoint=number # <– numbers who’ll receive an SMS message.
)
# Publish a message.
client.publish(Message=”Hello World!”, TopicArn=topic_arn, MessageAttributes={
‘AWS.SNS.SMS.SenderID’: {
‘DataType’: ‘String’,
‘StringValue’: ‘EASYORADBA’ # <– Name of Sender, Not Available in USA
},’AWS.SNS.SMS.SMSType’: {‘DataType’: ‘String’, ‘StringValue’: ‘Transactional’}})
Open 2 sessions and from one session run an UPDATE command on table ‘TEST’ and from another session execute the Python script. If you configured every properly, you will get an SMS from Sender ‘EASYORADBA’ wuth message text “Hello World”
4. Save Script & Schedule to run every minute in Crontab
* * * * * /usr/local/bin/python3.7 svl_statementtext_1min.py
This
script can be used in a variety of different scenarios to dispatch SMS
based on some count logic. Another scenario is to schedule this script
to check load errors on your Redshift cluster. Example run this script
in your Data loading window and check for errors in STL_LOAD_ERRORS
table. If there was a data loading issue then the Data Engineering team
can be notified via SMS. I am attaching the script (stl_load_errors.py)
to check for data loading errors. You can change the granuliarity of
time in which it should check for load errors by simply changing the
time intervsl in date_trunc function.
SQL : select count(*) from stl_load_errors where starttime > date_trunc(‘minute’, sysdate);
