Skip to content
This repository was archived by the owner on Apr 24, 2025. It is now read-only.

Commit fb4aaa3

Browse files
committed
Database and Cursor classes integration for database connection and queries execution (Unstable): 0.2
1 parent 7290b61 commit fb4aaa3

File tree

2 files changed

+123
-75
lines changed

2 files changed

+123
-75
lines changed

projects/DatabaseConnectionWithOOP/classes.py

Lines changed: 108 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import sqlite3
33

44
# Abstract Classes
5-
class AbstractDatabase():
5+
class AbstractDatabase(ABC):
66
@abstractmethod
77
def connect(self) -> None:
88
pass
@@ -12,13 +12,15 @@ def close(self) -> None:
1212
pass
1313

1414
# Interfaces
15-
class I_CustomSelectQuery:
15+
class I_CommonSelectQueries(ABC):
16+
@abstractmethod
1617
def execute_simple_select_query(self, table_name:str, fields:list[str]) -> list:
1718
pass
1819

19-
20-
# List of Inerfaces
21-
INTERFACES:list = [I_CustomSelectQuery]
20+
class I_CommonTableQueries(ABC):
21+
@abstractmethod
22+
def create_table(self, table_name:str, fields:list[str]) -> None:
23+
pass
2224

2325

2426
# Classes
@@ -33,25 +35,19 @@ def __init__(self, database_name:str) -> None:
3335
self.__database_name = database_name
3436
self.__conn = sqlite3.connect(f'{self.__database_name}.db')
3537

36-
@property
37-
def database_name(self) -> str:
38-
return self.__database_name
39-
40-
@property
41-
def conn(self) -> object | None:
42-
return self.__conn
43-
44-
def connect(self):
45-
"""
46-
Connects to a SQLite3 database.
47-
"""
48-
self.conn.connect()
49-
50-
def close(self):
51-
"""
52-
Closes database connection.
53-
"""
54-
self.conn.close()
38+
@property
39+
def database_name(self) -> str:
40+
return self.__database_name
41+
42+
@property
43+
def conn(self) -> object | None:
44+
return self.__conn
45+
46+
def close(self):
47+
"""
48+
Closes database connection.
49+
"""
50+
self.conn.close()
5551

5652
class Cursor():
5753
def __init__(self, database_object:Database) -> None:
@@ -64,26 +60,95 @@ def __init__(self, database_object:Database) -> None:
6460
self.database = database_object
6561
self.__cursor = self.database.__conn.cursor()
6662

67-
@property
68-
def cursor(self) -> object:
69-
return self.__cursor
63+
@property
64+
def cursor(self) -> object:
65+
return self.__cursor
66+
67+
def execute_query(self, query:str) -> list | None:
68+
"""
69+
The Cursor object executes an SQL query that the user will pass as str, for example 'SELECT * FROM Users WHERE age > 21'.
70+
71+
Attributes:
72+
- query (str): The query that will be executed, it can be of any type (SELECT, UPDATE, DELETE, INSERT, etc.).
73+
"""
74+
try:
75+
result = self.cursor.execute(query)
76+
print('Query was executed.')
77+
return result.fetchall() if result else []
78+
except Exception as e:
79+
print('Impossible to execute the query:', e)
80+
return None
81+
82+
# Custom cursor for most common queries execution.
83+
class CustomCursor(Cursor, I_CommonTableQueries, I_CommonSelectQueries):
84+
def __init__(self, database_object:Database):
85+
super().__init__(database_object)
86+
87+
def execute_query(self, query:str):
88+
"""
89+
Executes a simple query of any type wether SELECT, INSERT, CREATE TABLE, DELETE, etc.
90+
This method leverages its class's parent class method with the same name, behavior and attributes.
91+
92+
Attributes:
93+
- query (str): The query that will be executed.
94+
"""
95+
return super().execute_query(query)
96+
97+
def execute_simple_select_query(self, table_name:str, fields:list[str]) -> list:
98+
"""
99+
Executes a simple query of SELECT type with the fields to show provided as parameters and the name of the table.
100+
101+
Attributes:
102+
- table_name (str): Name of the table from where data is going to be obtained.
103+
- fields (list[str]): List of fields to fetch from the database's table.
104+
105+
Return:
106+
- data (list): List of rows obtained from the SELECT query in str format.
107+
"""
108+
query = f"""SELECT {', '.join(fields)} FROM {table_name};"""
109+
data = self.execute_query(query)
110+
return data
111+
112+
def create_table(self, table_name:str, fields:list[str]) -> None:
113+
"""
114+
Creates a table on the database based on the provided fields and table name.
115+
116+
Attributes:
117+
- table_name (): Name of the table that is going to be created.
118+
-fields (list): List of the table fields in string format.
119+
120+
Return:
121+
- None
122+
"""
70123

71-
def execute_query(self, query:str) -> list | None:
72-
"""
73-
The Cursor object executes an SQL query that the user will pass as str, for example 'SELECT * FROM Users WHERE age > 21'.
124+
# Format the fields from fields list in a single string
125+
formated_fields = ', '.join(fields)
126+
127+
query = f"""CREATE TABLE IF NOT EXISTS {table_name} ({formated_fields})"""
128+
self.execute_query(query)
129+
130+
def insert_rows(self, table_name:str, fields:list[str], values:list[list[str]]) -> bool:
131+
"""
132+
Executes a classic INSERT query receiving the name of the fields matching the values to insert and the name of the table
133+
This method iterates over every row on the provided list of values to make an insertion on the database in the table..
134+
135+
Attributes:
136+
- table_name (str): Name of the table where the data will be inserted as a new row.
137+
- fields (list[str]): List of fields to determine which type of data should be inserted.
138+
- values (list[list[str]]): List of rows to insert, every row is a list of every value in the desired format.
74139
75-
Attributes:
76-
- query (str): The query that will be executed, it can be of any type (SELECT, UPDATE, DELETE, INSERT, etc.).
77-
"""
140+
Return:
141+
- succes (str): True if rows were inserted. False if it was not possible to insert rows.
142+
"""
143+
formated_fields = ', '.join(fields)
144+
rows_list = values
145+
for row in rows_list:
78146
try:
79-
result = self.cusor.execute(query)
147+
formated_values = ', '.join(f"'{value}'" for value in row)
148+
query = f"""INSERT INTO {table_name} ({formated_fields}) VALUES({formated_values});"""
149+
self.execute_query(query)
80150
except Exception as e:
81-
print('Impossible to fetch result data:', e)
82-
finally:
83-
self.cursor.execute(query)
84-
85-
if result:
86-
print('Database query sucessfully executed!')
87-
return result
88-
print('Not result obtained from the database query execution, but it worked sucessfully!')
89-
return None
151+
print(f'Error during inserting data into database on table {table_name}:', e)
152+
succes = False
153+
succes = True
154+
return succes
Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,25 @@
1-
from . classes import Cursor, Database
2-
from . classes import INTERFACES
3-
4-
# Custom cursor for most common queries execution.
5-
class CustomCursor(Cursor, INTERFACES.I_CustomSelectQuery):
6-
def __init__(self, database_object:Database):
7-
super().__init__(database_object)
8-
9-
def execute_query(self, query:str):
10-
"""
11-
Executes a simple query of any type wether SELECT, INSERT, CREATE TABLE, DELETE, etc.
12-
This method leverages its class's parent class method with the same name, behavior and attributes.
13-
14-
Attributes:
15-
query (str): The query that will be executed.
16-
"""
17-
super().execute_query(query)
18-
19-
def execute_simple_select_query(self, table_name:str, fields:list[str]) -> list:
20-
table_name = table_name
21-
fields = fields
22-
query = f"""SELECT {[field for field in fields]} FROM {table_name};"""
23-
data = self.execute_query(query)
24-
return data
25-
26-
def create_table(self, table_name:str, fields:list[str]) -> None:
27-
self.execute_query("")
28-
pass
29-
"""Uncompleted yet"""
30-
1+
from classes import Database, CustomCursor
312

323

334
""" Now with a simple cursor object we can execute the most common queries like the typical 'SELECT', or create a table with ease reducing the SQL statement we have to provide to just parameters. """
345
my_database = Database('MyDatabase')
356
my_cursor = CustomCursor(my_database)
367

378
# Creating users table
38-
my_cursor.create_table('users')
9+
my_cursor.create_table('users', ['id INTEGER PRIMARY KEY AUTOINCREMENT', 'username TEXT UNIQUE NOT NULL', 'email TEXT UNIQUE NOT NULL', 'password TEXT NOT NULL', 'age INTEGER'])
10+
11+
# Inserting data in users table
12+
users_to_insert = [
13+
['Joaquin', '[email protected]', '123password', 22],
14+
['Aline', '[email protected]', '123password', 21],
15+
['Henry', '[email protected]', '123password', 35],
16+
['James', '[email protected]', '123password', 32],
17+
['Nicole', '[email protected]', '123password', 28],
18+
['Maria', '[email protected]', '123password', 38]
19+
]
20+
users_fields = ['username', 'email', 'password', 'age']
21+
my_cursor.insert_rows('users', users_fields, users_to_insert)
3922

4023
# Fetching data from database in users table
41-
result = my_cursor.execute_simple_select_query('users', ['username', 'email', 'password', 'age'])
24+
result = my_cursor.execute_simple_select_query('users', users_fields)
4225
print(result)

0 commit comments

Comments
 (0)