project-init
This commit is contained in:
commit
65691a0aee
7 files changed
+897
No files matched your search
@@ -0,0 +1,135 @@
|
||||
"""
|
||||
Database layer: connect to MySQL, verify/create the student_db database,
|
||||
and verify/create the STUDENT, GUARDIAN and ATTENDANCE tables per the
|
||||
schema (Tables 9.3, 9.4, 9.5).
|
||||
|
||||
Schema notes:
|
||||
- GUARDIAN.GUID is the primary key (12-digit Aadhaar number, stored as CHAR(12)).
|
||||
- STUDENT.GUID is a foreign key referencing GUARDIAN.GUID.
|
||||
- ATTENDANCE has a composite primary key (AttendanceDate, RollNumber), and
|
||||
RollNumber is also a foreign key referencing STUDENT.RollNumber.
|
||||
- Because STUDENT references GUARDIAN, GUARDIAN must be created first.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
import pymysql
|
||||
import pymysql.cursors
|
||||
|
||||
import config
|
||||
|
||||
# Table creation statements, in dependency order (GUARDIAN -> STUDENT -> ATTENDANCE)
|
||||
TABLE_DEFINITIONS = {
|
||||
"GUARDIAN": """
|
||||
CREATE TABLE GUARDIAN (
|
||||
GUID CHAR(12) NOT NULL,
|
||||
GName VARCHAR(20) NOT NULL,
|
||||
GPhone CHAR(10) NULL,
|
||||
GAddress VARCHAR(30) NOT NULL,
|
||||
PRIMARY KEY (GUID),
|
||||
UNIQUE (GPhone)
|
||||
) ENGINE=InnoDB
|
||||
""",
|
||||
"STUDENT": """
|
||||
CREATE TABLE STUDENT (
|
||||
RollNumber INT NOT NULL,
|
||||
SName VARCHAR(20) NOT NULL,
|
||||
SDateofBirth DATE NOT NULL,
|
||||
GUID CHAR(12) NOT NULL,
|
||||
PRIMARY KEY (RollNumber),
|
||||
FOREIGN KEY (GUID) REFERENCES GUARDIAN(GUID)
|
||||
ON DELETE RESTRICT ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB
|
||||
""",
|
||||
"ATTENDANCE": """
|
||||
CREATE TABLE ATTENDANCE (
|
||||
AttendanceDate DATE NOT NULL,
|
||||
RollNumber INT NOT NULL,
|
||||
AttendanceStatus CHAR(1) NOT NULL,
|
||||
PRIMARY KEY (AttendanceDate, RollNumber),
|
||||
FOREIGN KEY (RollNumber) REFERENCES STUDENT(RollNumber)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT chk_attendance_status CHECK (AttendanceStatus IN ('P', 'A'))
|
||||
) ENGINE=InnoDB
|
||||
""",
|
||||
}
|
||||
|
||||
# Creation order matters because of foreign keys.
|
||||
TABLE_ORDER = ["GUARDIAN", "STUDENT", "ATTENDANCE"]
|
||||
|
||||
|
||||
def connect_server(database=None):
|
||||
"""Connect to the MySQL server (optionally selecting a database)."""
|
||||
try:
|
||||
conn = pymysql.connect(
|
||||
host=config.DB_HOST,
|
||||
port=config.DB_PORT,
|
||||
user=config.DB_USER,
|
||||
password=config.DB_PASSWORD,
|
||||
database=database,
|
||||
connect_timeout=config.DB_CONNECT_TIMEOUT,
|
||||
cursorclass=pymysql.cursors.DictCursor,
|
||||
autocommit=False,
|
||||
)
|
||||
return conn
|
||||
except pymysql.err.OperationalError as e:
|
||||
print(f"\n[ERROR] Could not connect to MySQL server at "
|
||||
f"{config.DB_HOST}:{config.DB_PORT} as user '{config.DB_USER}'.")
|
||||
print(f" Details: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def ensure_database():
|
||||
"""Verify the student_db database exists; create it if it does not."""
|
||||
conn = connect_server(database=None)
|
||||
try:
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("SHOW DATABASES LIKE %s", (config.DB_NAME,))
|
||||
exists = cur.fetchone() is not None
|
||||
if exists:
|
||||
print(f"[OK] Database '{config.DB_NAME}' found.")
|
||||
else:
|
||||
print(f"[..] Database '{config.DB_NAME}' not found. Creating it...")
|
||||
cur.execute(
|
||||
f"CREATE DATABASE `{config.DB_NAME}` "
|
||||
"CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
|
||||
)
|
||||
conn.commit()
|
||||
print(f"[OK] Database '{config.DB_NAME}' created.")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def ensure_tables(conn):
|
||||
"""Verify each required table exists; create any that are missing."""
|
||||
with conn.cursor() as cur:
|
||||
cur.execute("SHOW TABLES")
|
||||
existing = {row[f"Tables_in_{config.DB_NAME}"] for row in cur.fetchall()}
|
||||
|
||||
for table in TABLE_ORDER:
|
||||
if table in existing:
|
||||
print(f"[OK] Table '{table}' found.")
|
||||
else:
|
||||
print(f"[..] Table '{table}' not found. Creating it...")
|
||||
with conn.cursor() as cur:
|
||||
cur.execute(TABLE_DEFINITIONS[table])
|
||||
conn.commit()
|
||||
print(f"[OK] Table '{table}' created.")
|
||||
|
||||
|
||||
def get_connection():
|
||||
"""
|
||||
Full startup sequence:
|
||||
1. Ensure the student_db database exists (creating it if needed).
|
||||
2. Connect to student_db.
|
||||
3. Ensure all required tables exist (creating any that are missing).
|
||||
Returns an open connection to student_db, ready for use.
|
||||
"""
|
||||
print(f"Connecting to MySQL server at {config.DB_HOST}:{config.DB_PORT} ...")
|
||||
ensure_database()
|
||||
|
||||
conn = connect_server(database=config.DB_NAME)
|
||||
print(f"[OK] Connected to database '{config.DB_NAME}'.")
|
||||
|
||||
ensure_tables(conn)
|
||||
return conn
|
||||
Reference in new issue
Block a user