diff --git a/.gitignore b/.gitignore
index 982311e..38493ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -128,4 +128,5 @@ dmypy.json
# Pyre type checker
.pyre/
main.py
-test.py
\ No newline at end of file
+test.py
+pyproject_backup.toml
\ No newline at end of file
diff --git a/README.md b/README.md
index 412fdee..1e98bce 100644
--- a/README.md
+++ b/README.md
@@ -16,15 +16,6 @@ $ pip install postgres-dynamic
## Parameter Format:
-- connection_string: dict
- ```Python
- connection_string = {
- 'PG_HOST': 'YOUR_CONNETION_HOST_ADDRESS',
- 'PG_DATABASE': 'YOUR_CONNECTION_DATABASE_NAME',
- 'PG_USER': 'YOUR_CONNECTION_USERNAME',
- 'PG_PASSWORD': 'YOUR_CONNECTION_PASSWORD',
- }
- ```
- connection_object: Callable
```Python
connection_object = psycopg2.connect(host,port,database,user,password) #object created from psycopg2.connect()
@@ -118,7 +109,6 @@ Example DB
Parameters:
```
- connection_string #required
main_table #required
where #required
join_table #optional (if omitted it won't join to any table)
@@ -133,12 +123,6 @@ Example DB
import asyncio
query_result = PGDGet.get_one(
- connection_string={
- 'PG_HOST': 'localhost', #using default port 5432
- 'PG_DATABASE': 'postgres',
- 'PG_USER': 'postgres',
- 'PG_PASSWORD': 'password'
- },
main_table={'table': 'employees'},
where=[
{'column_name': 'id', 'value': '1'},
@@ -156,12 +140,6 @@ Example DB
# with join table salaries
query_result = PGDGet.get_one(
- connection_string={
- 'PG_HOST': 'localhost', #using default port 5432
- 'PG_DATABASE': 'postgres',
- 'PG_USER': 'postgres',
- 'PG_PASSWORD': 'password'
- },
main_table={'table': 'employees', 'alias': 'emp'},
join_table=[
{'table': 'salaries', 'alias': 'sal', 'join_method': 'INNER', 'on': 'emp.id = sal.employee_id'}
@@ -185,7 +163,6 @@ Example DB
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)
@@ -206,12 +183,6 @@ Example DB
import asyncio
query_result = PGDGet.get_all(
- connection_string={
- 'PG_HOST': 'localhost', #using default port 5432
- 'PG_DATABASE': 'postgres',
- 'PG_USER': 'postgres',
- 'PG_PASSWORD': 'password'
- },
main_table={'table': 'employees'},
limit=3,
offset=2
@@ -231,7 +202,6 @@ Example DB
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)
@@ -243,12 +213,6 @@ Example DB
import asyncio
query_result = PGDGet.get_count(
- connection_string={
- 'PG_HOST': 'localhost', #using default port 5432
- 'PG_DATABASE': 'postgres',
- 'PG_USER': 'postgres',
- 'PG_PASSWORD': 'password'
- },
main_table={'table': 'employees'},
where=[{'column_name': 'first_name', 'value': 'Alex'}]
)
@@ -270,7 +234,6 @@ Example DB
Parameters:
```
- connection_object #required
main_table #required
column_and_value #required
commit #optional (if omitted, default value will be False which will not saving any changes to database)
@@ -283,9 +246,7 @@ Example DB
from postgres_dynamic import PGDTransaction
import asyncio
- connection_object = psycopg2.connect(database='postgres', host='localhost', port=5432, user='postgres', password='password')
query_result = PGDTransaction.insert(
- connection_object=connection_object,
main_table='employees',
column_and_value={'id': 6, 'first_name': 'Harrison', 'last_name': 'Ford'},
commit=True
@@ -301,9 +262,7 @@ Example DB
```Python
# without auto commit
- connection_object = psycopg2.connect(database='postgres', host='localhost', port=5432, user='postgres', password='password')
query_result = PGDTransaction.insert(
- connection_object=connection_object,
main_table='salaries',
column_and_value={'employee_id': 6, 'salary': 250000},
)
@@ -330,7 +289,6 @@ Example DB
Parameters:
```
- connection_object #required
main_table #required
column_and_value #required
where #required
@@ -344,9 +302,7 @@ Example DB
from postgres_dynamic import PGDTransaction
import asyncio
- connection_object = psycopg2.connect(database='postgres', host='localhost', port=5432, user='postgres', password='password')
query_result = PGDTransaction.update(
- connection_object=connection_object,
main_table='employees',
column_and_value={'first_name': 'Tyler', 'last_name': 'Oakley'},
where=[
@@ -365,9 +321,7 @@ Example DB
```Python
# without auto commit
- connection_object = psycopg2.connect(database='postgres', host='localhost', port=5432, user='postgres', password='password')
query_result = PGDTransaction.update(
- connection_object=connection_object,
main_table='salaries',
column_and_value={'salary': 450000},
where=[
@@ -398,7 +352,6 @@ Example DB
Parameters:
```
- connection_object #required
main_table #required
where #required
commit #optional (if omitted, default value will be False which will not saving any changes to database)
@@ -411,9 +364,7 @@ Example DB
from postgres_dynamic import PGDTransaction
import asyncio
- connection_object = psycopg2.connect(database='postgres', host='localhost', port=5432, user='postgres', password='password')
query_result = PGDTransaction.delete(
- connection_object=connection_object,
main_table='salaries',
where=[
{'column_name': 'employee_id', 'value': '6'},
@@ -431,9 +382,7 @@ Example DB
```Python
# without auto commit
- connection_object = psycopg2.connect(database='postgres', host='localhost', port=5432, user='postgres', password='password')
query_result = PGDTransaction.delete(
- connection_object=connection_object,
main_table='employees',
where=[
{'column_name': 'id', 'value': '6'},
diff --git a/pyproject.toml b/pyproject.toml
index 9744fcf..585f408 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,15 +4,12 @@ build-backend = "setuptools.build_meta"
[project]
name = "postgres-dynamic"
-version = "0.0.6"
+version = "0.0.11"
authors = [
{ name="Bayu Satria Gemilang", email="bayu.code.lab@gmail.com" },
]
-description = "Fast API Google Cloud Storage"
+description = "Postgres Dynamic Query"
readme = "README.md"
-dependencies = [
- "psycopg2>=2.9.3"
-]
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Python :: 3",
diff --git a/src/postgres_dynamic/pgd_connection.py b/src/postgres_dynamic/pgd_connection.py
deleted file mode 100644
index 83fce41..0000000
--- a/src/postgres_dynamic/pgd_connection.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import psycopg2
-
-class PGDConnection:
- def __init__(self, connection_string: dict, query: str, values: tuple) -> None:
- self.query = query
- self.values = values
- self.connection = psycopg2.connect(
- host = connection_string['PG_HOST'],
- database = connection_string['PG_DATABASE'],
- user = connection_string['PG_USER'],
- password = connection_string['PG_PASSWORD']
- )
- self.cursor = self.connection.cursor()
-
- def __enter__(self):
- self.cursor.execute(self.query, self.values)
- return self.cursor
-
- def __exit__(self, exc_type, exc_value, exc_traceback):
- self.connection.close()
- self.cursor.close
\ No newline at end of file
diff --git a/src/postgres_dynamic/pgd_get.py b/src/postgres_dynamic/pgd_get.py
index 4509be2..986f624 100644
--- a/src/postgres_dynamic/pgd_get.py
+++ b/src/postgres_dynamic/pgd_get.py
@@ -1,22 +1,13 @@
from typing import Awaitable, Optional
-from datetime import datetime, timedelta
-from postgres_dynamic.pgd_connection import PGDConnection
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]:
+ async def get_one(cls, 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=[
@@ -32,7 +23,6 @@ async def get_one(cls, connection_string: dict, main_table: dict, where: list, j
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 '*'
query = """
SELECT {column_name} FROM {main_table} {main_table_alias} {join_table} WHERE {where_query}
@@ -45,36 +35,23 @@ async def get_one(cls, connection_string: dict, main_table: dict, where: list, j
join_query = ''
for i in join_table:
- join_query += ' INNER JOIN' if i['join_method'] == 'INNER' else ' LEFT JOIN' if i['join_method'] == 'LEFT' else ' RIGHT JOIN'
+ join_query += ' INNER JOIN' if i['join_method'] == 'INNER' else ' LEFT JOIN' if i['join_method'] == 'LEFT' else ' RIGHT JOIN' if i['join_method'] == 'RIGHT' else ' FULL JOIN' if i['join_method'] == 'FULL' else ' JOIN'
join_query += f' {i["table"]} {i["alias"]} ON {i["on"]}'
query = query.format(column_name=column_name, 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'] for wv in where)
- values = where_values
- with PGDConnection(connection_string, query, values) as cursor:
- column_name = [i[0] for i in cursor.description]
- data = cursor.fetchone()
- if data:
- for a, b in zip(column_name, data):
- result[a] = str(b + timedelta(hours=7)) if type(b) is datetime else b
- return result
+ where_value = tuple(wv['value'] for wv in where)
+ value = where_value
+ return query, value
except Exception as e:
raise e
@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]:
+ async def get_all(cls, 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=[
@@ -96,7 +73,6 @@ async def get_all(cls, connection_string: dict, main_table: dict, where: list =
offset=1 #optional
"""
try:
- result = []
column_name = ','.join(column_name) if column_name else '*'
query = """
SELECT {column_name} FROM {main_table} {main_table_alias} {join_table} {where_query} {order_query} LIMIT %s OFFSET %s
@@ -115,38 +91,23 @@ async def get_all(cls, connection_string: dict, main_table: dict, where: list =
join_query = ''
for i in join_table:
- join_query += ' INNER JOIN' if i['join_method'] == 'INNER' else ' LEFT JOIN' if i['join_method'] == 'LEFT' else ' RIGHT JOIN'
+ join_query += ' INNER JOIN' if i['join_method'] == 'INNER' else ' LEFT JOIN' if i['join_method'] == 'LEFT' else ' RIGHT JOIN' if i['join_method'] == 'RIGHT' else ' FULL JOIN' if i['join_method'] == 'FULL' else ' JOIN'
join_query += f' {i["table"]} {i["alias"]} ON {i["on"]}'
query = query.format(column_name=column_name, 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, order_query=order_query)
- where_values = tuple(wv['value'] for wv in where)
+ where_value = tuple(wv['value'] for wv in where)
offset_value = (limit*(offset-1)) if offset else None
- values = where_values + (limit, offset_value)
- with PGDConnection(connection_string, query, values) as cursor:
- column_name = [i[0] for i in cursor.description]
- for i in cursor.fetchall():
- data = {}
- for a, b in zip(column_name, i):
- data[a] = str(b + timedelta(hours=7)) if type(b) is datetime else b
- result.append(data)
- return {'data': result}
+ value = where_value + (limit, offset_value)
+ return query, value
except Exception as e:
raise e
@classmethod
- async def get_count(cls, connection_string: dict, main_table: dict, where: list = [], join_table:list = []) -> Awaitable[dict]:
+ async def get_count(cls, 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=[
@@ -160,7 +121,6 @@ async def get_count(cls, connection_string: dict, main_table: dict, where: list
#conjunction only required when providing more than one dictionary
"""
try:
- result = []
query = """
SELECT COUNT(*) FROM {main_table} {main_table_alias} {join_table} {where_query}
"""
@@ -174,14 +134,12 @@ async def get_count(cls, connection_string: dict, main_table: dict, where: list
join_query = ''
for i in join_table:
- join_query += ' INNER JOIN' if i['join_method'] == 'INNER' else ' LEFT JOIN' if i['join_method'] == 'LEFT' else ' RIGHT JOIN'
+ join_query += ' INNER JOIN' if i['join_method'] == 'INNER' else ' LEFT JOIN' if i['join_method'] == 'LEFT' else ' RIGHT JOIN' if i['join_method'] == 'RIGHT' else ' FULL JOIN' if i['join_method'] == 'FULL' else ' JOIN'
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'] for wv in where)
- values = where_values
- with PGDConnection(connection_string, query, values) as cursor:
- result = cursor.fetchone()[0]
- return {'total_data': result}
+ where_value = tuple(wv['value'] for wv in where)
+ value = where_value
+ return query, value
except Exception as e:
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 8827ea8..d12c682 100644
--- a/src/postgres_dynamic/pgd_transaction.py
+++ b/src/postgres_dynamic/pgd_transaction.py
@@ -1,13 +1,12 @@
from typing import Awaitable
class PGDTransaction:
@classmethod
- async def insert(cls, connection_object: any, main_table: str, column_and_value: dict, commit: bool = False) -> Awaitable[None]:
+ async def insert(cls, main_table: str, column_and_value: dict, commit: bool = False) -> Awaitable[None]:
"""Dynamic query to insert certain table that can target several columns
Params supplied for column_and_values are dict that contains key, value pair
Example parameters:
- connection_object = psycopg2.connect(database='postgres', host='localhost', user='postgres', password='password')
main_table='employees',
@@ -22,20 +21,15 @@ async def insert(cls, connection_object: any, main_table: str, column_and_value:
"""
query = query_template.format(main_table=main_table, column_keys=column_keys, column_values=', '.join(['%s']*(len(column_and_value))))
value = tuple([value for value in column_and_value.values()])
- connection_object.cursor().execute(query, value)
- if commit:
- connection_object.commit()
- return
+ return query, value
except Exception as e:
- connection_object.rollback()
raise e
@classmethod
- async def update(cls, connection_object: any, main_table: str, column_and_value: dict, where: list, commit: bool = False) -> Awaitable[None]:
+ async def update(cls, 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
Example parameters:
- connection_object = psycopg2.connect(database='postgres', host='localhost', user='postgres', password='password')
main_table='employees',
@@ -62,20 +56,15 @@ async def update(cls, connection_object: any, main_table: str, column_and_value:
update_values = tuple(value for value in column_and_value.values())
where_values = tuple(wv['value'] for wv in where)
value = update_values + where_values
- connection_object.cursor().execute(query, value)
- if commit:
- connection_object.commit()
- return
+ return query, value
except Exception as e:
- connection_object.rollback()
raise e
@classmethod
- async def delete(cls, connection_object: any, main_table: str, where: list, commit: bool = False) -> Awaitable[None]:
+ async def delete(cls, main_table: str, where: list, commit: bool = False) -> Awaitable[None]:
"""Dynamic query to delete data from certain table that can takes several conditions
Example parameters:
- connection_object = psycopg2.connect(database='postgres', host='localhost', user='postgres', password='password')
main_table='employees',
@@ -97,10 +86,6 @@ async def delete(cls, connection_object: any, main_table: str, where: list, comm
"""
query = query_template.format(main_table=main_table, where_query=where_query)
value = tuple(wv['value'] for wv in where)
- connection_object.cursor().execute(query, value)
- if commit:
- connection_object.commit()
- return
+ return query, value
except Exception as e:
- connection_object.rollback()
raise e
\ No newline at end of file