-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
358 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
[email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# mysqlexample | ||
|
||
Describe your project here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[project] | ||
name = "mysqlexample" | ||
version = "0.1.0" | ||
description = "Add your description here" | ||
authors = [ | ||
{ name = "pan93412", email = "[email protected]" } | ||
] | ||
dependencies = [ | ||
"sqlalchemy>=2.0.23", | ||
"mysql-connector-python>=8.2.0", | ||
] | ||
readme = "README.md" | ||
requires-python = ">= 3.8" | ||
|
||
[build-system] | ||
requires = ["hatchling"] | ||
build-backend = "hatchling.build" | ||
|
||
[tool.rye] | ||
managed = true | ||
dev-dependencies = [ | ||
"black>=23.11.0", | ||
] | ||
|
||
[tool.hatch.metadata] | ||
allow-direct-references = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# generated by rye | ||
# use `rye lock` or `rye sync` to update this lockfile | ||
# | ||
# last locked with the following flags: | ||
# pre: false | ||
# features: [] | ||
# all-features: false | ||
|
||
-e file:. | ||
black==23.11.0 | ||
click==8.1.7 | ||
mypy-extensions==1.0.0 | ||
mysql-connector-python==8.2.0 | ||
packaging==23.2 | ||
pathspec==0.11.2 | ||
platformdirs==4.1.0 | ||
protobuf==4.21.12 | ||
sqlalchemy==2.0.23 | ||
typing-extensions==4.8.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# generated by rye | ||
# use `rye lock` or `rye sync` to update this lockfile | ||
# | ||
# last locked with the following flags: | ||
# pre: false | ||
# features: [] | ||
# all-features: false | ||
|
||
-e file:. | ||
mysql-connector-python==8.2.0 | ||
protobuf==4.21.12 | ||
sqlalchemy==2.0.23 | ||
typing-extensions==4.8.0 |
17 changes: 17 additions & 0 deletions
17
semester-3/python-iii/flask-231206/src/mysqlexample/01-create-db-connector.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import os | ||
from mysql.connector import connection | ||
|
||
# Connect to MySQL server | ||
with connection.MySQLConnection(user='root', password=os.environ["MYSQL_PASSWORD"], | ||
host='localhost') as cnx: | ||
cursor = cnx.cursor() | ||
|
||
# Get the version of the MySQL server | ||
cursor.execute("SELECT VERSION()") | ||
result = cursor.fetchone() | ||
print(result) | ||
|
||
# Create a database if not exist. | ||
cursor.execute("CREATE DATABASE IF NOT EXISTS example_c DEFAULT CHARSET utf8 COLLATE utf8_general_ci") | ||
|
||
cnx.commit() |
14 changes: 14 additions & 0 deletions
14
semester-3/python-iii/flask-231206/src/mysqlexample/01-create-db-sqlalchemy.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import os | ||
from sqlalchemy import String, create_engine, select, text, func | ||
|
||
# Create a connection to the database | ||
engine = create_engine(f'mysql+mysqlconnector://root:{os.environ["MYSQL_PASSWORD"]}@localhost') | ||
|
||
with engine.connect() as connection: | ||
# Get the current version of the MySQL server | ||
result = connection.execute(select(func.version(type_=String()))) | ||
print(result.first()) | ||
|
||
# Create a database if not exist. | ||
connection.execute(text("CREATE DATABASE IF NOT EXISTS example_sa DEFAULT CHARSET utf8 COLLATE utf8_general_ci")) | ||
connection.commit() |
24 changes: 24 additions & 0 deletions
24
semester-3/python-iii/flask-231206/src/mysqlexample/02-create-table-connector.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import os | ||
from mysql.connector import connection | ||
# Connect to MySQL server | ||
with connection.MySQLConnection(user='root', password=os.environ["MYSQL_PASSWORD"], | ||
host='localhost', database='example_c') as cnx: | ||
|
||
cursor = cnx.cursor() | ||
|
||
# Create a stu_data table, with: | ||
# stu_no as primary key | ||
# stu_name | ||
# stu_class | ||
# stu_phone | ||
|
||
# Create a table if not exist. | ||
cursor.execute(( | ||
"CREATE TABLE IF NOT EXISTS stu_data (" | ||
"stu_no VARCHAR(10) PRIMARY KEY," | ||
"stu_name VARCHAR(255) NOT NULL," | ||
"stu_class VARCHAR(255) NOT NULL," | ||
"stu_phone VARCHAR(10) NOT NULL)" | ||
)) | ||
|
||
cnx.commit() |
35 changes: 35 additions & 0 deletions
35
semester-3/python-iii/flask-231206/src/mysqlexample/03-insert-data-connector.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import os | ||
from mysql.connector import connection | ||
# Connect to MySQL server | ||
with connection.MySQLConnection(user='root', password=os.environ["MYSQL_PASSWORD"], | ||
host='localhost', database='example_c') as cnx: | ||
cursor = cnx.cursor() | ||
|
||
# Insert data into stu_data table | ||
cursor.executemany( | ||
"INSERT INTO stu_data (stu_no, stu_name, stu_class, stu_phone) VALUES (%s, %s, %s, %s)", | ||
[ | ||
# 15 mock data | ||
("C111156101", "王小明", "智商二甲", "0912345678"), | ||
("C111156102", "陳小華", "智商二甲", "0913579246"), | ||
("C111156103", "林小美", "智商二甲", "0912345678"), | ||
("C111156104", "張小強", "智商二甲", "0913579246"), | ||
("C111156105", "李大雄", "智商二甲", "0912345678"), | ||
("C111156106", "黃小琪", "智商二甲", "0913579246"), | ||
("C111156107", "吳小菁", "智商二甲", "0912345678"), | ||
("C111156108", "劉小偉", "智商二甲", "0913579246"), | ||
("C111156109", "蔡小娟", "智商二甲", "0912345678"), | ||
("C111156110", "許小儒", "智商二甲", "0913579246"), | ||
("C111156111", "林小雨", "智商二甲", "0912345678"), | ||
("C111156112", "陳小風", "智商二甲", "0913579246"), | ||
("C111156113", "黃小雲", "智商二甲", "0912345678"), | ||
("C111156114", "張小翰", "智商二甲", "0913579246"), | ||
("C111156115", "王小明", "智商二甲", "0912345678"), | ||
] | ||
) | ||
cnx.commit() | ||
|
||
# Get all datas from stu_data table | ||
cursor.execute("SELECT * FROM stu_data") | ||
result = cursor.fetchall() | ||
print(result) |
51 changes: 51 additions & 0 deletions
51
semester-3/python-iii/flask-231206/src/mysqlexample/03-insert-data-sqlalchemy.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import os | ||
from sqlalchemy import Column, MetaData, String, Table, create_engine, insert, select | ||
|
||
# Create a connection to the database | ||
engine = create_engine(f'mysql+mysqlconnector://root:{os.environ["MYSQL_PASSWORD"]}@localhost/example_sa') | ||
|
||
# Create a metadata with the tables. | ||
metadata = MetaData() | ||
|
||
# Create a stu_data table, with: | ||
# stu_no as primary key | ||
# stu_name | ||
# stu_class | ||
# stu_phone | ||
Student = Table( | ||
"students", | ||
metadata, | ||
Column("stu_no", String(10), primary_key=True), | ||
Column("stu_name", String(255), nullable=False), | ||
Column("stu_class", String(255), nullable=False), | ||
Column("stu_phone", String(10), nullable=False), | ||
) | ||
|
||
with engine.connect() as connection: | ||
# Create a table if not exist. | ||
metadata.create_all(engine) | ||
|
||
# Insert data into stu_data table | ||
stmt = insert(Student).values([ | ||
{"stu_no": "C111156101", "stu_name": "王小明", "stu_class": "智商二甲", "stu_phone": "0912345678"}, | ||
{"stu_no": "C111156102", "stu_name": "陳小華", "stu_class": "智商二甲", "stu_phone": "0913579246"}, | ||
{"stu_no": "C111156103", "stu_name": "林小美", "stu_class": "智商二甲", "stu_phone": "0912345678"}, | ||
{"stu_no": "C111156104", "stu_name": "張小強", "stu_class": "智商二甲", "stu_phone": "0913579246"}, | ||
{"stu_no": "C111156105", "stu_name": "李大雄", "stu_class": "智商二甲", "stu_phone": "0912345678"}, | ||
{"stu_no": "C111156106", "stu_name": "黃小琪", "stu_class": "智商二甲", "stu_phone": "0913579246"}, | ||
{"stu_no": "C111156107", "stu_name": "吳小菁", "stu_class": "智商二甲", "stu_phone": "0912345678"}, | ||
{"stu_no": "C111156108", "stu_name": "劉小偉", "stu_class": "智商二甲", "stu_phone": "0913579246"}, | ||
{"stu_no": "C111156109", "stu_name": "蔡小娟", "stu_class": "智商二甲", "stu_phone": "0912345678"}, | ||
{"stu_no": "C111156110", "stu_name": "許小儒", "stu_class": "智商二甲", "stu_phone": "0913579246"}, | ||
{"stu_no": "C111156111", "stu_name": "林小雨", "stu_class": "智商二甲", "stu_phone": "0912345678"}, | ||
{"stu_no": "C111156112", "stu_name": "陳小風", "stu_class": "智商二甲", "stu_phone": "0913579246"}, | ||
]) | ||
result = connection.execute(stmt) | ||
print("Inserted %d rows" % result.rowcount) | ||
connection.commit() | ||
|
||
# Get all datas from stu_data table | ||
stmt = select(Student) | ||
result = connection.execute(stmt) | ||
print(result.fetchall()) | ||
|
15 changes: 15 additions & 0 deletions
15
semester-3/python-iii/flask-231206/src/mysqlexample/04-select-data-connector.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import os | ||
from mysql.connector import connection | ||
# Connect to MySQL server | ||
with connection.MySQLConnection(user='root', password=os.environ["MYSQL_PASSWORD"], | ||
host='localhost', database='example_c') as cnx: | ||
cursor = cnx.cursor() | ||
|
||
# 輸入一個學號,查詢該學生的資料 | ||
stu_no = input("請輸入學號: ") | ||
|
||
# 從資料庫查詢特定資料 | ||
cursor.execute("SELECT * FROM stu_data WHERE stu_no = %s", (stu_no,)) | ||
|
||
result = cursor.fetchone() | ||
print(result) |
28 changes: 28 additions & 0 deletions
28
semester-3/python-iii/flask-231206/src/mysqlexample/04-select-data-sqlalchemy.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import os | ||
from sqlalchemy import Column, MetaData, String, Table, create_engine, insert, select | ||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session | ||
|
||
# Create a connection to the database | ||
engine = create_engine(f'mysql+mysqlconnector://root:{os.environ["MYSQL_PASSWORD"]}@localhost/example_sa') | ||
|
||
|
||
class Base(DeclarativeBase): pass | ||
|
||
class Student(Base): | ||
__tablename__ = "students" | ||
|
||
stu_no: Mapped[str] = mapped_column(String(10), primary_key=True) | ||
stu_name: Mapped[str] = mapped_column(String(255), nullable=False) | ||
stu_class: Mapped[str] = mapped_column(String(255), nullable=False) | ||
stu_phone: Mapped[str] = mapped_column(String(10), nullable=False) | ||
|
||
def __repr__(self): | ||
return f"<Student(stu_no='{self.stu_no}', stu_name='{self.stu_name}', stu_class='{self.stu_class}', stu_phone='{self.stu_phone}')>" | ||
|
||
with Session(engine) as session: | ||
# Ask user to input a student number | ||
stu_no = input("請輸入學號: ") | ||
|
||
student = session.get(Student, stu_no) | ||
|
||
print(student if student else "Not found.") |
112 changes: 112 additions & 0 deletions
112
semester-3/python-iii/flask-231206/src/mysqlexample/05-update-data-with-gui.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import os | ||
from sqlalchemy import String, create_engine | ||
from sqlalchemy.exc import SQLAlchemyError | ||
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session | ||
import tkinter | ||
import tkinter.messagebox | ||
from tkinter.ttk import Button, Entry, Frame, Label | ||
|
||
|
||
class Base(DeclarativeBase): pass | ||
|
||
class Student(Base): | ||
__tablename__ = "students" | ||
|
||
stu_no: Mapped[str] = mapped_column(String(10), primary_key=True) | ||
stu_name: Mapped[str] = mapped_column(String(255), nullable=False) | ||
stu_class: Mapped[str] = mapped_column(String(255), nullable=False) | ||
stu_phone: Mapped[str] = mapped_column(String(10), nullable=False) | ||
|
||
def __repr__(self): | ||
return f"<Student(stu_no='{self.stu_no}', stu_name='{self.stu_name}', stu_class='{self.stu_class}', stu_phone='{self.stu_phone}')>" | ||
|
||
# Create a tkinter window | ||
window = tkinter.Tk() | ||
window.title("查詢並修改學生資料") | ||
|
||
# Create a connection to the database | ||
engine = create_engine(f'mysql+mysqlconnector://root:{os.environ["MYSQL_PASSWORD"]}@localhost/example_sa') | ||
session = Session(engine) | ||
|
||
# Allow users to input a student number | ||
id_input_frame = Frame(window) | ||
id_input_frame.pack(padx=10, pady=10) | ||
|
||
id_input_entry_frame = Frame(id_input_frame) | ||
id_input_entry_frame.pack() | ||
stu_no_label = Label(id_input_entry_frame, text="學號") | ||
stu_no_label.grid(row=0, column=0) | ||
stu_no_entry = Entry(id_input_entry_frame) | ||
stu_no_entry.grid(row=0, column=1) | ||
stu_query_btn = Button(id_input_frame, text="查詢") | ||
stu_query_btn.pack() | ||
|
||
# Show the student data | ||
stu_data_frame = Frame(window) | ||
stu_data_frame.pack(padx=10, pady=10) | ||
stu_input_frame = Frame(stu_data_frame) | ||
stu_input_frame.pack() | ||
stu_name_label = Label(stu_input_frame, text="姓名") | ||
stu_name_label.grid(row=0, column=0) | ||
stu_name_entry = Entry(stu_input_frame) | ||
stu_name_entry.grid(row=0, column=1) | ||
stu_class_label = Label(stu_input_frame, text="班級") | ||
stu_class_label.grid(row=1, column=0) | ||
stu_class_entry = Entry(stu_input_frame) | ||
stu_class_entry.grid(row=1, column=1) | ||
stu_phone_label = Label(stu_input_frame, text="電話") | ||
stu_phone_label.grid(row=2, column=0) | ||
stu_phone_entry = Entry(stu_input_frame) | ||
stu_phone_entry.grid(row=2, column=1) | ||
stu_modify_btn_frame = Frame(stu_data_frame) | ||
stu_modify_btn_frame.pack() | ||
stu_update_btn = Button(stu_modify_btn_frame, text="修改") | ||
stu_update_btn.grid(row=0, column=0) | ||
|
||
|
||
current_selected_student: str | None = None | ||
|
||
def select() -> None: | ||
global current_selected_student | ||
|
||
current_selected_student = stu_no_entry.get() | ||
student = session.get(Student, current_selected_student) | ||
|
||
# Write student's value to the entry | ||
if student: | ||
stu_name_entry.delete(0, tkinter.END) | ||
stu_name_entry.insert(0, student.stu_name) | ||
stu_class_entry.delete(0, tkinter.END) | ||
stu_class_entry.insert(0, student.stu_class) | ||
stu_phone_entry.delete(0, tkinter.END) | ||
stu_phone_entry.insert(0, student.stu_phone) | ||
else: | ||
tkinter.messagebox.showinfo("查詢", "查無此學生") | ||
current_selected_student = None | ||
|
||
|
||
def update() -> None: | ||
global current_selected_student | ||
|
||
if current_selected_student is None: | ||
tkinter.messagebox.showerror("修改", "請先查詢學生") | ||
return | ||
|
||
student = session.get(Student, current_selected_student) | ||
|
||
try: | ||
assert student is not None | ||
student.stu_name = stu_name_entry.get() | ||
student.stu_class = stu_class_entry.get() | ||
student.stu_phone = stu_phone_entry.get() | ||
session.commit() | ||
tkinter.messagebox.showinfo("修改", "修改成功") | ||
except AssertionError: | ||
tkinter.messagebox.showerror("修改", "查無此學生") | ||
except SQLAlchemyError as e: | ||
tkinter.messagebox.showerror("修改", f"修改失敗: {e}") | ||
|
||
stu_query_btn.bind("<Button-1>", lambda event: select()) | ||
stu_update_btn.bind("<Button-1>", lambda event: update()) | ||
|
||
window.mainloop() |