From d6c504a6e3e5faf3534aaea99fc7345da20a151e Mon Sep 17 00:00:00 2001 From: Iftikar Tsani Date: Tue, 1 Nov 2022 10:30:33 +0700 Subject: [PATCH 1/2] update --- README.md | 41 +++++++++++++-- src/postgres_dynamic/pgd_get.py | 88 ++++++++++++++++++++++++++++++++- 2 files changed, 122 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index ea08d8a..7d37eb5 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ The purpose of this library is for better managament and maintenance of the code ``` connection_string = { 'PG_HOST': 'YOUR_CONNETION_HOST_ADDRESS', - 'PG_PORT': 'YOUR_CONNECTION_PORT', 'PG_DATABASE': 'YOUR_CONNECTION_DATABASE_NAME', 'PG_USER': 'YOUR_CONNECTION_USERNAME', 'PG_PASSWORD': 'YOUR_CONNECTION_PASSWORD', @@ -124,7 +123,6 @@ Example DB query_result = PGDGet.get_one( connection_string={ 'PG_HOST': 'localhost', - 'PG_PORT': 5432, 'PG_DATABASE': 'postgres', 'PG_USER': 'postgres', 'PG_PASSWORD': 'password' @@ -148,7 +146,6 @@ Example DB query_result = PGDGet.get_one( connection_string={ 'PG_HOST': 'localhost', - 'PG_PORT': 5432, 'PG_DATABASE': 'postgres', 'PG_USER': 'postgres', 'PG_PASSWORD': 'password' @@ -169,7 +166,7 @@ Example DB ``` - - Multi Select + - Multi Select Multi select always return a dict with key `data`, based on `fetchall` in psycopg2 and returning a list of dictionary with `{column_name: value}` of the tables. Parameters:
@@ -199,7 +196,6 @@ Example DB query_result = PGDGet.get_all( connection_string={ 'PG_HOST': 'localhost', - 'PG_PORT': 5432, 'PG_DATABASE': 'postgres', 'PG_USER': 'postgres', 'PG_PASSWORD': 'password' @@ -216,6 +212,41 @@ Example DB ```
+- Select count + Select count always return a dict with key `total_data`, based on `SELECT COUNT(*)` in SQL and returning a dictionary with `{total_data: value}` of the query. + Parameters: +
+ Show more... + + ``` + connection_string #required + main_table #required + where #optional (if omitted no condition will be passed) + join_table #optional (if omitted it won't join to any table) + ``` + + Code samples: + ``` + from postgres_dynamic import PGDGet + import asyncio + + query_result = PGDGet.get_count( + connection_string={ + 'PG_HOST': 'localhost', + 'PG_DATABASE': 'postgres', + 'PG_USER': 'postgres', + 'PG_PASSWORD': 'password' + }, + main_table={'table': 'employees'}, + where=[{'column_name': 'first_name', 'value': 'Alex'}] + ) + + result = asyncio.run(query_result) + print(result) + + # {'total_data': 1} + ``` +
- INSERT diff --git a/src/postgres_dynamic/pgd_get.py b/src/postgres_dynamic/pgd_get.py index 284bcee..e0ce130 100644 --- a/src/postgres_dynamic/pgd_get.py +++ b/src/postgres_dynamic/pgd_get.py @@ -5,6 +5,32 @@ class PGDGet: @classmethod async def get_one(cls, connection_string: dict, main_table: dict, where: list, join_table:list = [], column_name: list = None) -> Awaitable[dict]: + """Get one always return a single value from the query, based on fetchone in psycopg2 and returning a dictionary with {column_name: value} of the tables. + Please refer to documentation for thorough guide. + + Example parameters: + + connection_string={ + 'PG_HOST': 'localhost', #using default port 5432 + 'PG_DATABASE': 'postgres', + 'PG_USER': 'postgres', + 'PG_PASSWORD': 'password' + } + + main_table={'table': 'employees', 'alias': 'emp'} #alias can be omitted + + join_table=[ + {'table': 'salaries', 'alias': 'sal', 'join_method': 'INNER', 'on': 'emp.id = sal.emp_id'} + ] + #optional + + where=[ + {'column_name': 'id', 'value': '1', 'operator': '=', 'conjunction': 'AND'}, #operator and conjunction can be omitted + ] + #conjunction only required when providing more than one dictionary + + column_name=['first_name'] #can be omitted, when omitted it equals as `select * from blabla` + """ try: result = {} column_name = ','.join(column_name) if column_name else '*' @@ -37,6 +63,38 @@ async def get_one(cls, connection_string: dict, main_table: dict, where: list, j @classmethod async def get_all(cls, connection_string: dict, main_table: dict, where: list = [], join_table:list = [], order: dict = {}, column_name: list = None, limit: Optional[int] = None, offset: Optional[int] = None) -> Awaitable[dict]: + """Get all always return a dict with key data, based on fetchall in psycopg2 and returning a list of dictionary with {column_name: value} of the tables. + Please refer to documentation for thorough guide. + + Example parameters: + + connection_string={ + 'PG_HOST': 'localhost', #using default port 5432 + 'PG_DATABASE': 'postgres', + 'PG_USER': 'postgres', + 'PG_PASSWORD': 'password' + } + + main_table={'table': 'employees', 'alias': 'emp'} #alias can be omitted + + join_table=[ + {'table': 'salaries', 'alias': 'sal', 'join_method': 'INNER', 'on': 'emp.id = sal.emp_id'} + ] + #optional + + where=[ + {'column_name': 'id', 'value': '1', 'operator': '=', 'conjunction': 'AND'}, #operator and conjunction can be omitted + ] + #conjunction only required when providing more than one dictionary + + column_name=['first_name'] #can be omitted, when omitted it equals as `select * from blabla` + + order={'first_name': 'ASC'} #optional + + limit=5 #optional + + offset=1 #optional + """ try: result = [] column_name = ','.join(column_name) if column_name else '*' @@ -77,6 +135,30 @@ async def get_all(cls, connection_string: dict, main_table: dict, where: list = @classmethod async def get_count(cls, connection_string: dict, main_table: dict, where: list = [], join_table:list = []) -> Awaitable[dict]: + """Get count always return a dict with key total_data, based on select count(*) in SQL and returning a dictionary with {total_data: value} of the query. + Please refer to documentation for thorough guide. + + Example parameters: + + connection_string={ + 'PG_HOST': 'localhost', #using default port 5432 + 'PG_DATABASE': 'postgres', + 'PG_USER': 'postgres', + 'PG_PASSWORD': 'password' + } + + main_table={'table': 'employees', 'alias': 'emp'} #alias can be omitted + + join_table=[ + {'table': 'salaries', 'alias': 'sal', 'join_method': 'INNER', 'on': 'emp.id = sal.emp_id'} + ] + #optional + + where=[ + {'column_name': 'id', 'value': '1', 'operator': '=', 'conjunction': 'AND'}, #operator and conjunction can be omitted + ] + #conjunction only required when providing more than one dictionary + """ try: result = [] query = """ @@ -96,10 +178,12 @@ async def get_count(cls, connection_string: dict, main_table: dict, where: list join_query += f' {i["table"]} {i["alias"]} ON {i["on"]}' query = query.format(main_table=main_table['table'], main_table_alias=main_table['alias'] if main_table.get('alias') else '', join_table=join_query, where_query=where_query) - where_values = tuple(wv['value'] if isinstance(wv['value'], str) else tuple(wv['value']) for wv in where ) + where_values = tuple(wv['value'] for wv in where) values = where_values with PGDConnection(connection_string, query, values) as cursor: result = cursor.fetchone()[0] return {'total_data': result} except Exception as e: - raise e \ No newline at end of file + raise e + +PGDGet.get_one() \ No newline at end of file From 3193f290b7b3a9b469bd3ff3a10de30fc6ee476f Mon Sep 17 00:00:00 2001 From: Iftikar Tsani Date: Tue, 1 Nov 2022 10:44:44 +0700 Subject: [PATCH 2/2] update docstring and readme --- README.md | 2 +- src/postgres_dynamic/pgd_get.py | 4 +-- src/postgres_dynamic/pgd_transaction.py | 39 ++++++++++++++++++++----- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 732b410..412fdee 100644 --- a/README.md +++ b/README.md @@ -224,7 +224,7 @@ Example DB ``` -- Select count + - Select count Select count always return a dict with key `total_data`, based on `SELECT COUNT(*)` in SQL and returning a dictionary with `{total_data: value}` of the query. Parameters:
diff --git a/src/postgres_dynamic/pgd_get.py b/src/postgres_dynamic/pgd_get.py index e0ce130..4509be2 100644 --- a/src/postgres_dynamic/pgd_get.py +++ b/src/postgres_dynamic/pgd_get.py @@ -184,6 +184,4 @@ async def get_count(cls, connection_string: dict, main_table: dict, where: list result = cursor.fetchone()[0] return {'total_data': result} except Exception as e: - raise e - -PGDGet.get_one() \ No newline at end of file + raise e \ No newline at end of file diff --git a/src/postgres_dynamic/pgd_transaction.py b/src/postgres_dynamic/pgd_transaction.py index cb6297d..8827ea8 100644 --- a/src/postgres_dynamic/pgd_transaction.py +++ b/src/postgres_dynamic/pgd_transaction.py @@ -6,9 +6,14 @@ async def insert(cls, connection_object: any, main_table: str, column_and_value: Params supplied for column_and_values are dict that contains key, value pair - Usage: - example query -> INSERT INTO table(col_1, col_2) VALUES (val_1, val_2) - input params ex-> column_and_value = {col_1: value_1, col_2: value_2} + Example parameters: + connection_object = psycopg2.connect(database='postgres', host='localhost', user='postgres', password='password') + + main_table='employees', + + column_and_value={'id': 6, 'first_name': 'Harrison', 'last_name': 'Ford'}, + + commit=True #optional, if omitted commit=False """ try: column_keys = ', '.join([key for key in column_and_value.keys()]) @@ -29,8 +34,19 @@ async def insert(cls, connection_object: any, main_table: str, column_and_value: async def update(cls, connection_object: any, main_table: str, column_and_value: dict, where: list, commit: bool = False) -> Awaitable[None]: """Dynamic query to update certain table that can takes multiple conditions and target several columns - Params supplied for column_and_values and condition are dict that contains key, value pair - Multiple conditions are concatenated in query using 'AND' clause + Example parameters: + connection_object = psycopg2.connect(database='postgres', host='localhost', user='postgres', password='password') + + main_table='employees', + + column_and_value={'id': 6, 'first_name': 'Tyler', 'last_name': 'Oakley'}, + + commit=True #optional, if omitted commit=False + + where=[ + {'column_name': 'id', 'value': '1', 'operator': '=', 'conjunction': 'AND'}, #operator and conjunction can be omitted + ] + #conjunction only required when providing more than one dictionary """ try: column_query = ', '.join([key + ' = %s' for key in column_and_value.keys()]) @@ -58,8 +74,17 @@ async def update(cls, connection_object: any, main_table: str, column_and_value: async def delete(cls, connection_object: any, main_table: str, where: list, commit: bool = False) -> Awaitable[None]: """Dynamic query to delete data from certain table that can takes several conditions - Params supplied for conditions are dict that contains key, value pair - Multiple conditions are concatenated in query using 'AND' clause + Example parameters: + connection_object = psycopg2.connect(database='postgres', host='localhost', user='postgres', password='password') + + main_table='employees', + + commit=True #optional, if omitted commit=False + + where=[ + {'column_name': 'id', 'value': '1', 'operator': '=', 'conjunction': 'AND'}, #operator and conjunction can be omitted + ] + #conjunction only required when providing more than one dictionary """ try: where_query=''