Skip to content
Merged
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
38 changes: 36 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ $ pip install postgres-dynamic
```Python
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',
Expand Down Expand Up @@ -179,7 +178,7 @@ Example DB
```
</details>

- 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:
<details>
Expand Down Expand Up @@ -225,6 +224,41 @@ Example DB
```
</details>

- 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:
<details>
<summary>Show more...</summary>

```
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:
```Python
from postgres_dynamic import PGDGet
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'}]
)

result = asyncio.run(query_result)
print(result)

# {'total_data': 1}
```
</details>


- INSERT
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "postgres-dynamic"
version = "0.0.5"
version = "0.0.6"
authors = [
{ name="Bayu Satria Gemilang", email="bayu.code.lab@gmail.com" },
]
Expand Down
84 changes: 83 additions & 1 deletion src/postgres_dynamic/pgd_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 '*'
Expand Down Expand Up @@ -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 '*'
Expand Down Expand Up @@ -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 = """
Expand All @@ -96,7 +178,7 @@ 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]
Expand Down
39 changes: 32 additions & 7 deletions src/postgres_dynamic/pgd_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()])
Expand All @@ -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()])
Expand Down Expand Up @@ -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=''
Expand Down