diff --git a/dbpro.py b/dbpro.py new file mode 100644 index 0000000..3f510e4 --- /dev/null +++ b/dbpro.py @@ -0,0 +1,180 @@ +import psycopg2 + + +DB_NAME = "project-1" +DB_USER = "postgres" +DB_PASS = "sql321!" +DB_HOST = "localhost" +DB_PORT = 5432 + +conn = None +cursor = None + +try: +# 1. create database connection + conn = psycopg2.connect( + host=DB_HOST, database=DB_NAME, user=DB_USER, + password=DB_PASS, port=DB_PORT + ) + print("Database connection successful!") + cursor = conn.cursor() + +# 2. Create tables + print("\nCreating tables...") + create_employees_table_sql = """ + CREATE TABLE IF NOT EXISTS employees ( + emp_id INT PRIMARY KEY, + first_name VARCHAR(50), + last_name VARCHAR(50), + salary INT, + job_title VARCHAR(100), + gender VARCHAR(10), + hire_date DATE, + dept_id INT + ); + """ + create_departments_table_sql = """ + CREATE TABLE IF NOT EXISTS departments ( + dept_id INT PRIMARY KEY, + dept_name VARCHAR(100) + ); + """ + cursor.execute(create_employees_table_sql) + cursor.execute(create_departments_table_sql) + conn.commit() + print("Tables 'employees' and 'departments' created or already exist.") + +# 3. Insert sample data + print("\nInserting data...") + insert_departments_data_sql = """ + INSERT INTO departments (dept_id, dept_name) VALUES + (13, 'Operations'), (14, 'Marketing'), (12, 'Technology'), (11, 'Administrative') + ON CONFLICT (dept_id) DO NOTHING; + """ + insert_employees_data_sql = """ + INSERT INTO employees (emp_id, first_name, last_name, salary, job_title, gender, hire_date, dept_id) VALUES + (17679, 'Robert', 'Gilmore', 110000, 'Operations Director', 'Male', '2018-09-04', 13), + (26650, 'Elvis', 'Ritter', 86000, 'Sales Manager', 'Male', '2017-11-24', 14), + (30840, 'David', 'Barrow', 85000, 'Data Scientist', 'Male', '2019-12-02', 12), + (49714, 'Hugo', 'Forester', 55000, 'IT Support Specialist', 'Male', '2019-11-22', 12), + (51821, 'Linda', 'Foster', 95000, 'Data Scientist', 'Female', '2019-04-29', 12), + (67323, 'Lisa', 'Wiener', 75000, 'Business Analyst', 'Female', '2018-09-08', 14), + (70950, 'Rodney', 'Weaver', 87000, 'Project Manager', 'Male', '2018-12-20', 13), + (71329, 'Gayle', 'Meyer', 77000, 'HR Manager', 'Female', '2019-06-28', 11), + (76589, 'Jason', 'Christian', 99000, 'Project Manager', 'Male', '2019-01-21', 13), + (97927, 'Bill', 'Lanning', 67000, 'Web Developer', 'Female', '2018-06-25', 12) + ON CONFLICT (emp_id) DO NOTHING; + """ + cursor.execute(insert_departments_data_sql) + cursor.execute(insert_employees_data_sql) + conn.commit() + print("Sample data inserted or already exists.") + +# 4. Execute and display results for all 10 queries + print("\n--- Query Results ---") + +# 1, to find employees who get paid more than Rodney Weaver. + print("\n1. Employees paid more than Rodney Weaver:") + query1 = """ + SELECT emp_id, first_name, last_name, salary + FROM employees + WHERE salary > (SELECT salary FROM employees WHERE first_name = 'Rodney' AND last_name = 'Weaver'); + """ + cursor.execute(query1) + for row in cursor.fetchall(): + print(row) + +# 2, to find the average, min and max salaries. + print("\n2. Average, Min, Max Salaries:") + query2 = "SELECT AVG(salary), MIN(salary), MAX(salary) FROM employees;" + cursor.execute(query2) + print(cursor.fetchone()) + +# 3, to find employees whose salary is more than 8700. + print("\n3. Employees with salary > 8700:") + query3 = "SELECT first_name, last_name, salary FROM employees WHERE salary > 8700;" + cursor.execute(query3) + for row in cursor.fetchall(): + print(row) + +# 4, to find employees who work under the Operations department. + print("\n4. Employees in Operations department:") + query4 = """ + SELECT e.first_name, e.last_name + FROM employees e JOIN departments d ON e.dept_id = d.dept_id + WHERE d.dept_name = 'Operations'; + """ + cursor.execute(query4) + for row in cursor.fetchall(): + print(row) + +# 5, to find employees who work under the Technology department. + print("\n5. Employees in Technology department:") + query5 = """ + SELECT e.first_name, e.last_name + FROM employees e JOIN departments d ON e.dept_id = d.dept_id + WHERE d.dept_name = 'Technology'; + """ + cursor.execute(query5) + for row in cursor.fetchall(): + print(row) + +# 6, find the average salary of female employees. + print("\n6. Average salary of female employees:") + query6 = "SELECT AVG(salary) FROM employees WHERE gender = 'Female';" + cursor.execute(query6) + print(cursor.fetchone()) + +# 7, find the average salaries of each department. + print("\n7. Average salaries per department:") + query7 = """ + SELECT d.dept_name, AVG(e.salary) + FROM employees e JOIN departments d ON e.dept_id = d.dept_id + GROUP BY d.dept_name; + """ + cursor.execute(query7) + for row in cursor.fetchall(): + print(row) + +# 8, find the oldest and newest employees. + print("\n8. Oldest and Newest Employees (by hire_date):") + query8 = """ + (SELECT emp_id, first_name, last_name, hire_date FROM employees ORDER BY hire_date ASC LIMIT 1) + UNION ALL + (SELECT emp_id, first_name, last_name, hire_date FROM employees ORDER BY hire_date DESC LIMIT 1); + """ + cursor.execute(query8) + for row in cursor.fetchall(): + print(row) + +# 9, find the hiring date and department of the highest paid employee. + print("\n9. Hiring date and department of highest paid employee:") + query9 = """ + SELECT e.hire_date, d.dept_name + FROM employees e JOIN departments d ON e.dept_id = d.dept_id + ORDER BY e.salary DESC LIMIT 1; + """ + cursor.execute(query9) + print(cursor.fetchone()) + +# 10, find the hiring date and department of the lowest paid employee. + print("\n10. Hiring date and department of lowest paid employee:") + query10 = """ + SELECT e.hire_date, d.dept_name + FROM employees e JOIN departments d ON e.dept_id = d.dept_id + ORDER BY e.salary ASC LIMIT 1; + """ + cursor.execute(query10) + print(cursor.fetchone()) + +except Exception as e: + print(f"An error occurred: {e}") + if conn: + conn.rollback() # Rollback any changes on error +finally: +# 5. Close cursor and connection + if cursor: + cursor.close() + if conn: + conn.close() + print("\nScript finished. Database connection closed.") \ No newline at end of file diff --git a/post.py b/post.py new file mode 100644 index 0000000..5684733 --- /dev/null +++ b/post.py @@ -0,0 +1,112 @@ +import psycopg2 + + +DB_NAME = "crm-project" +DB_USER = "postgres" +DB_PASS = "sql321!" +DB_HOST = "localhost" +DB_PORT = 5432 + +def create_tables(connection): + """ + Executes SQL queries to create all CRM project tables. + Uses the table schemas from 'crm-create-tables-sql-short'. + """ + cursor = None + try: + cursor = connection.cursor() + +# SQL for Trainees Table + create_trainees_sql = """ + CREATE TABLE IF NOT EXISTS Trainees ( + TraineeID SERIAL PRIMARY KEY, FullName VARCHAR(255) NOT NULL, + EmailAddress VARCHAR(255) UNIQUE NOT NULL, PhoneNumber VARCHAR(20), + PostalCode VARCHAR(20), StateOfResidence VARCHAR(100) + ); + """ + cursor.execute(create_trainees_sql) + print("Trainees table created or already exists.") + +# SQL for Applications Table + create_applications_sql = """ + CREATE TABLE IF NOT EXISTS Applications ( + ApplicationID SERIAL PRIMARY KEY, TraineeID INT NOT NULL, Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CurrentStatus VARCHAR(50), WillJoinITPHTraining BOOLEAN, FinancialStatus VARCHAR(50), + AttendingLanguageCourse BOOLEAN, EnglishLevel VARCHAR(20), DutchLevel VARCHAR(20), + UnderPressure BOOLEAN, CompletedBootcamp BOOLEAN, AttendedOnlineITCourse BOOLEAN, + ITExperience TEXT, IncludedInProject BOOLEAN, WillingnessToWork TEXT, + MotivationForJoining TEXT, ApplicationTerm VARCHAR(50), + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE CASCADE + ); + """ + cursor.execute(create_applications_sql) + print("Applications table created or already exists.") + +# SQL for Mentors Table + create_mentors_sql = """ + CREATE TABLE IF NOT EXISTS Mentors ( + MentorID SERIAL PRIMARY KEY, MeetingDate DATE NOT NULL, MentorFullName VARCHAR(255) NOT NULL, + TraineeID INT, HasRelevantKnowledge BOOLEAN, EligibleForVITProject BOOLEAN, + Thoughts TEXT, AvailabilityStatus VARCHAR(50), Comments TEXT, + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE SET NULL + ); + """ + cursor.execute(create_mentors_sql) + print("Mentors table created or already exists.") + +# SQL for Users Table + create_users_sql = """ + CREATE TABLE IF NOT EXISTS Users ( + UserID SERIAL PRIMARY KEY, Username VARCHAR(50) UNIQUE NOT NULL, + Password VARCHAR(255) NOT NULL, Role VARCHAR(50) NOT NULL + ); + """ + cursor.execute(create_users_sql) + print("Users table created or already exists.") + +# SQL for ProjectTracking Table + create_project_tracking_sql = """ + CREATE TABLE IF NOT EXISTS ProjectTracking ( + ProjectTrackingID SERIAL PRIMARY KEY, TraineeID INT NOT NULL, + ProjectSubmissionDate DATE, ProjectReviewDate DATE, + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE CASCADE + ); + """ + cursor.execute(create_project_tracking_sql) + print("ProjectTracking table created or already exists.") + + connection.commit() # Commit all table creation changes + print("\nAll CRM tables setup complete!") + + except psycopg2.Error as e: + print(f"Error creating tables: {e}") + if connection: + connection.rollback() # Rollback changes if an error occurs + finally: + if cursor: + cursor.close() + +# --- Main execution block --- +if __name__ == "__main__": + connection = None + try: +# create database connection + connection = psycopg2.connect( + host=DB_HOST, + database=DB_NAME, + user=DB_USER, + password=DB_PASS, + port=DB_PORT + ) + print("Database connection successful!") + +# Call the function to create tables + create_tables(connection) + + except Exception as e: + print(f"Connection or execution error: {e}") + finally: +# Close the connection + if connection: + connection.close() + print("Database connection closed.") \ No newline at end of file diff --git a/task_4.py b/task_4.py new file mode 100644 index 0000000..f5a70d7 --- /dev/null +++ b/task_4.py @@ -0,0 +1,105 @@ +import psycopg2 + + +DB_NAME = "dbtask4" +DB_USER = "postgres" +DB_PASS = "sql321!" +DB_HOST = "localhost" +DB_PORT = 5432 + +conn = None +cursor = None + +try: +# 1. establish database connection + conn = psycopg2.connect( + host=DB_HOST, database=DB_NAME, user=DB_USER, + password=DB_PASS, port=DB_PORT + ) + print("Database connection successful!") + cursor = conn.cursor() + +# 2. create CRM tables (all 5 tables) + print("\nCreating CRM tables...") + create_table_queries = [ + """ + CREATE TABLE IF NOT EXISTS Trainees ( + TraineeID SERIAL PRIMARY KEY, FullName VARCHAR(255) NOT NULL, + EmailAddress VARCHAR(255) UNIQUE NOT NULL, PhoneNumber VARCHAR(20), + PostalCode VARCHAR(20), StateOfResidence VARCHAR(100) + ); + """, + """ + CREATE TABLE IF NOT EXISTS Applications ( + ApplicationID SERIAL PRIMARY KEY, TraineeID INT NOT NULL, Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CurrentStatus VARCHAR(50), WillJoinITPHTraining BOOLEAN, FinancialStatus VARCHAR(50), + AttendingLanguageCourse BOOLEAN, EnglishLevel VARCHAR(20), DutchLevel VARCHAR(20), + UnderPressure BOOLEAN, CompletedBootcamp BOOLEAN, AttendedOnlineITCourse BOOLEAN, + ITExperience TEXT, IncludedInProject BOOLEAN, WillingnessToWork TEXT, + MotivationForJoining TEXT, ApplicationTerm VARCHAR(50), + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE CASCADE + ); + """, + """ + CREATE TABLE IF NOT EXISTS Mentors ( + MentorID SERIAL PRIMARY KEY, MeetingDate DATE NOT NULL, MentorFullName VARCHAR(255) NOT NULL, + TraineeID INT, HasRelevantKnowledge BOOLEAN, EligibleForVITProject BOOLEAN, + Thoughts TEXT, AvailabilityStatus VARCHAR(50), Comments TEXT, + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE SET NULL + ); + """, + """ + CREATE TABLE IF NOT EXISTS Users ( + UserID SERIAL PRIMARY KEY, Username VARCHAR(50) UNIQUE NOT NULL, + Password VARCHAR(255) NOT NULL, Role VARCHAR(50) NOT NULL + ); + """, + """ + CREATE TABLE IF NOT EXISTS ProjectTracking ( + ProjectTrackingID SERIAL PRIMARY KEY, TraineeID INT NOT NULL, + ProjectSubmissionDate DATE, ProjectReviewDate DATE, + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE CASCADE + ); + """ + ] + for query in create_table_queries: + cursor.execute(query) + conn.commit() + print("All CRM tables created or already exist.") + +# 3. insert Sample Data into Trainees (from TASK 4 example) + print("\nInserting sample trainee data...") + insert_trainee_query = """ + INSERT INTO Trainees (FullName, EmailAddress, PhoneNumber, PostalCode, StateOfResidence) + VALUES (%s, %s, %s, %s, %s) + ON CONFLICT (EmailAddress) DO NOTHING; -- Avoids errors if run multiple times + """ +# this list simulates data you would import from cloud files + trainee_data_to_insert = [ + ("Ahmet Yılmaz", "ahmet@example.com", "5551234567", "12345", "Istanbul"), + ("Ayşe Demir", "ayse@example.com", "5559876543", "67890", "Ankara"), + ("Cem Kaya", "cem@example.com", "5551112233", "54321", "Izmir"), + ("Buse Can", "buse@example.com", "5554445566", "98765", "İzmir"), + ("Deniz Arı", "deniz@example.com", "5557778899", "11223", "Bursa") + ] + cursor.executemany(insert_trainee_query, trainee_data_to_insert) + conn.commit() + print(f"{cursor.rowcount} trainee records inserted/updated.") + +# 4. verify data in Trainees table (optional) + print("\nVerifying trainees in database (first 5):") + cursor.execute("SELECT TraineeID, FullName, EmailAddress FROM Trainees LIMIT 5;") + for row in cursor.fetchall(): + print(row) + +except Exception as e: + print(f"An error occurred: {e}") + if conn: + conn.rollback() # Rollback changes if an error occurred +finally: +# 5. close cursor and connection + if cursor: + cursor.close() + if conn: + conn.close() + print("Database connection closed.") diff --git a/task_5.py b/task_5.py new file mode 100644 index 0000000..053c506 --- /dev/null +++ b/task_5.py @@ -0,0 +1,168 @@ +import psycopg2 + + +DB_NAME = "dbtask5" +DB_USER = "postgres" +DB_PASS = "sql321!" +DB_HOST = "localhost" +DB_PORT = 5432 + +class DatabaseManager: + """Manages PostgreSQL connections and query execution.""" + def __init__(self, dbname, user, password, host, port): + self.dbname = dbname + self.user = user + self.password = password + self.host = host + self.port = port + self.conn = None + + def connect(self): + """Establishes connection to the database.""" + try: + self.conn = psycopg2.connect( + dbname=self.dbname, user=self.user, + password=self.password, host=self.host, port=self.port + ) + print("Database connection successful!") + return True + except Exception as e: + print(f"Connection error: {e}") + self.conn = None + return False + + def close(self): + """Closes the database connection.""" + if self.conn: + self.conn.close() + print("Database connection closed.") + self.conn = None + + def execute_query(self, sql_query, params=None, fetch_results=False): + """Executes an SQL query, returning results if specified.""" + if not self.conn: + print("No database connection available.") + return None + + cursor = None + try: + cursor = self.conn.cursor() + cursor.execute(sql_query, params) + if fetch_results: + return cursor.fetchall() + else: + self.conn.commit() + return True + except Exception as e: + print(f"Query execution error: {e}") + if self.conn: + self.conn.rollback() # Rollback changes on error + return None + finally: + if cursor: + cursor.close() + +class Trainee: + """Represents a Trainee entity with its attributes.""" + def __init__(self, trainee_id, full_name, email_address, phone_number, postal_code, state_of_residence): + self.trainee_id = trainee_id + self.full_name = full_name + self.email_address = email_address + self.phone_number = phone_number + self.postal_code = postal_code + self.state_of_residence = state_of_residence + + def __repr__(self): + return (f"Trainee(ID={self.trainee_id}, Name='{self.full_name}', " + f"Email='{self.email_address}')") + +# --- Main Application Logic --- +if __name__ == "__main__": + db_manager = DatabaseManager(DB_NAME, DB_USER, DB_PASS, DB_HOST, DB_PORT) + + if db_manager.connect(): + try: +# 1. Create CRM Tables + print("\nCreating CRM tables...") + create_table_queries = [ + """ + CREATE TABLE IF NOT EXISTS Trainees ( + TraineeID SERIAL PRIMARY KEY, FullName VARCHAR(255) NOT NULL, + EmailAddress VARCHAR(255) UNIQUE NOT NULL, PhoneNumber VARCHAR(20), + PostalCode VARCHAR(20), StateOfResidence VARCHAR(100) + ); + """, + """ + CREATE TABLE IF NOT EXISTS Applications ( + ApplicationID SERIAL PRIMARY KEY, TraineeID INT NOT NULL, Timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + CurrentStatus VARCHAR(50), WillJoinITPHTraining BOOLEAN, FinancialStatus VARCHAR(50), + AttendingLanguageCourse BOOLEAN, EnglishLevel VARCHAR(20), DutchLevel VARCHAR(20), + UnderPressure BOOLEAN, CompletedBootcamp BOOLEAN, AttendedOnlineITCourse BOOLEAN, + ITExperience TEXT, IncludedInProject BOOLEAN, WillingnessToWork TEXT, + MotivationForJoining TEXT, ApplicationTerm VARCHAR(50), + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE CASCADE + ); + """, + """ + CREATE TABLE IF NOT EXISTS Mentors ( + MentorID SERIAL PRIMARY KEY, MeetingDate DATE NOT NULL, MentorFullName VARCHAR(255) NOT NULL, + TraineeID INT, HasRelevantKnowledge BOOLEAN, EligibleForVITProject BOOLEAN, + Thoughts TEXT, AvailabilityStatus VARCHAR(50), Comments TEXT, + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE SET NULL + ); + """, + """ + CREATE TABLE IF NOT EXISTS Users ( + UserID SERIAL PRIMARY KEY, Username VARCHAR(50) UNIQUE NOT NULL, + Password VARCHAR(255) NOT NULL, Role VARCHAR(50) NOT NULL + ); + """, + """ + CREATE TABLE IF NOT EXISTS ProjectTracking ( + ProjectTrackingID SERIAL PRIMARY KEY, TraineeID INT NOT NULL, + ProjectSubmissionDate DATE, ProjectReviewDate DATE, + FOREIGN KEY (TraineeID) REFERENCES Trainees(TraineeID) ON DELETE CASCADE + ); + """ + ] + for query in create_table_queries: + db_manager.execute_query(query) # Use db_manager to execute + print("All CRM tables created or already exist.") + +# 2. Insert Sample Data into Trainees + print("\nInserting sample trainee data...") + insert_trainee_query = """ + INSERT INTO Trainees (FullName, EmailAddress, PhoneNumber, PostalCode, StateOfResidence) + VALUES (%s, %s, %s, %s, %s) + ON CONFLICT (EmailAddress) DO NOTHING; + """ + trainee_data_to_insert = [ + ("Ahmet Yılmaz", "ahmet@example.com", "5551234567", "12345", "Istanbul"), + ("Ayşe Demir", "ayse@example.com", "5559876543", "67890", "Ankara"), + ("Cem Kaya", "cem@example.com", "5551112233", "54321", "Izmir"), + ("Buse Can", "buse@example.com", "5554445566", "98765", "İzmir"), + ("Deniz Arı", "deniz@example.com", "5557778899", "11223", "Bursa") + ] +# Use cursor.executemany via a temporary cursor to use db_manager for this + with db_manager.conn.cursor() as temp_cursor: + temp_cursor.executemany(insert_trainee_query, trainee_data_to_insert) + db_manager.conn.commit() + print(f"{temp_cursor.rowcount} trainee records inserted/updated.") + + +# 3. Fetch and display data from the database (replacing 'cloud queries') + print("\nFetching and displaying trainees from the database:") + select_all_trainees_query = "SELECT TraineeID, FullName, EmailAddress, PhoneNumber, PostalCode, StateOfResidence FROM Trainees;" + results = db_manager.execute_query(select_all_trainees_query, fetch_results=True) + + if results: + trainees = [Trainee(*row) for row in results] + for trainee in trainees: + print(trainee) + else: + print("No trainees found in the database.") + + except Exception as e: + print(f"An error occurred during project execution: {e}") + finally: + db_manager.close() \ No newline at end of file