Dry-run sql query using psycopg2 on Redshift in Python

Introduction

I implemented the process to execute SQL query in Redshift using psycopg2 in Python, but I implemented it in a wrapper class to execute it with dry-run, so I will introduce how it was implemented I think that I want to do it.

Wrapper class implementation

Wrap psycopg2 to implement dry-run functionality. When executing a query, do not commit, but rollback to perform dry-run.

wrapper.py


import os
import psycopg2
import re

class DBWrapperClass:

    __is_dryrun = False #The default is dry-run do not run

    def __init__(self):
        self.__connection()

    def __connection(self):
        #DB connection information Please change accordingly
        dsn = {
            "host" : os.environ.get('DB_HOST'),
            "port" : os.environ.get('DB_PORT'),
            "database" : os.environ.get('DB_NAME'),
            "user" : os.environ.get('DB_USER'),
            "password" : os.environ.get('DB_PASS'),
        }

        self.__conn = psycopg2.connect(**dsn)

    #Allows you to specify arguments with with syntax
    def __call__(self, **kwargs):
        self.__is_dryrun = bool(kwargs['dryrun']) if 'dryrun' in kwargs else False
        return self

    #Get cursor with with syntax
    def __enter__(self):
        self.__cursor = self.__conn.cursor()
        return self

    #Commit or rollback at the end of the with syntax and close the cursor
    def __exit__(self, exc_type, exc_value, traceback):
        #Roll back if an exception occurs
        needs_rollback = True if exc_value else False

        self.__commit(needs_rollback)
        self.__close_cursor()

        #If you do not call it like a function with with syntax, the previous value will be inherited, so initialize it.
        self.__is_dryrun = False

    def __commit(self, needs_rollback=False):
        if self.__conn:
            # dry-When you need a run or rollback
            if self.__is_dryrun or needs_rollback:
                self.__conn.rollback()
            else:
                self.__conn.commit()

    #close cursor
    def __close_cursor(self):
        if self.__conn:
            self.__cursor.close()


    #Close the connection
    def close(self):
        if self.__conn:
            self.__conn.close()

    #Execute the query
    def execute(self, sql):
        # dry-For run, truncate is not executed
        #Since truncate cannot roll back, this control is included.
        if not (self.__is_dryrun and re.match(r'^\s*truncate\s+', sql, flags=re.IGNORECASE)):
            self.__cursor.execute(sql)

In order to be able to manage cursor with with syntax like psycopg2, processing related to cursor is implemented in each method of __enter__ and __exit__. We've also added a __call__ method so that you can set the dry-run specification in the with syntax.

Run dry-run in wrapper class

import wrapper

try:
    dbwrapper = wrapper.DBWrapperClass()
    with dbwrapper(dryrun=True) as db:
        #dry sql-Run with run
        db.execute('dry-sql you want to run with run')

finally:
    if 'dbwrapper' in locals():
        dbwrapper.close()

On the execution side, this is all you need to do. This time, only the argument for dry-run is set to make it as simple as possible, but it will be more convenient if other setting values ​​such as autocommit can also be set with the argument.

Summary

I implemented the wrapper class of psycopg2 and added the function of dry-run. I usually write programs in php, so I thought the with syntax of python was quite convenient. Also, what I thought about implementing this time is that python has quite a lot of magic methods and I definitely want to use it when implementing classes for different purposes.

Recommended Posts

Dry-run sql query using psycopg2 on Redshift in Python
Notes on using code formatter in Python
Notes on using dict in python [Competition Pro]
Broadcast on LINE using python
Translate using googletrans in Python
Using Python mode in Processing
[Treasure Data] [Python] Execute a query on Treasure Data using TD Client
GUI programming in Python using Appjar
Precautions when using pit in Python
Introducing Python using pyenv on Ubuntu 20.04
Notes on using MeCab from Python
Preparing python using vscode on ubuntu
Try using LevelDB in Python (plyvel)
[Python ORM] Notation when writing SQL using subquery in IN clause in SQLAlchemy
Using global variables in python functions
Study on Tokyo Rent Using Python (3-2)
Notes on installing Python using PyEnv
Try to log in to Netflix automatically using python on your PC
Let's see using input in python
Infinite product in Python (using functools)
Edit videos in Python using MoviePy
Notes on using rstrip with python.
Install Python on CentOS using Pyenv
Study on Tokyo Rent Using Python (3-3)
Handwriting recognition using KNN in Python
Try using Leap Motion in Python
Depth-first search using stack in Python
Install Python on CentOS using pyenv
When using regular expressions in Python
GUI creation in python using tkinter 2
Deploy and use the prediction model created in Python on SQL Server
Notes for using OpenCV on Windows10 Python 3.8.3.
Mouse operation using Windows API in Python
Notes using cChardet and python3-chardet in Python 3.3.1.
Try using the Wunderlist API in Python
GUI creation in python using tkinter part 1
Execute Python code on C ++ (using Boost.Python)
Get Suica balance in Python (using libpafe)
Slowly hash passwords using bcrypt in Python
Detect "brightness" using python on Raspberry Pi 3!
Try using the Kraken API in Python
Using venv in Windows + Docker environment [Python]
Find files like find on linux in Python
Notes on nfc.ContactlessFrontend () for nfcpy in python
Install python library on Lambda using [/ tmp]
Tweet using the Twitter API in Python
[Python] [Windows] Serial communication in Python using DLL
Run AzureKinect in Python on Christmas Eve.
I tried using Bayesian Optimization in Python
Log in to Slack using requests in Python
Get Youtube data in Python using Youtube Data API
Using physical constants in Python scipy.constants ~ constants e ~
Scraping a website using JavaScript in Python
Run servomotor on Raspberry Pi 3 using python
Develop slack bot in python using chat.postMessage
Write python modules in fortran using f2py
Draw a tree in Python 3 using graphviz
Study on Tokyo Rent Using Python (3-1 of 3)
Notes for using python (pydev) in eclipse
Disease classification in Random Forest using Python
Detect temperature using python on Raspberry Pi 3!