From 812dc64e22a9bf3f61b81b8ba35d8c28c31b5819 Mon Sep 17 00:00:00 2001 From: chiayu Date: Mon, 8 Sep 2025 16:20:32 +0800 Subject: [PATCH] Initial commit --- Data/pizza.xlsx | Bin 0 -> 8970 bytes flask_pizza_api.py | 193 ++++++++++++++++++++++++++++++++++++++++++ insert_pizza_data.py | 63 ++++++++++++++ read_pizza_excel.py | 17 ++++ test_db_connection.py | 53 ++++++++++++ 新文字文件.txt | 0 6 files changed, 326 insertions(+) create mode 100644 Data/pizza.xlsx create mode 100644 flask_pizza_api.py create mode 100644 insert_pizza_data.py create mode 100644 read_pizza_excel.py create mode 100644 test_db_connection.py create mode 100644 新文字文件.txt diff --git a/Data/pizza.xlsx b/Data/pizza.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..bbcdae1d739a9c8dd9318d850d33dfca9ace2fe0 GIT binary patch literal 8970 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", methods=["GET"]) +def get_pizza(id): + try: + conn = get_db_connection() + cursor = conn.cursor(dictionary=True) + + cursor.execute("SELECT * FROM pizza WHERE id = %s", (id,)) + pizza = cursor.fetchone() + + if not pizza: + return error_response(404, "Pizza not found") + + return success_response(pizza) + + except Exception as e: + return error_response(500, str(e)) + finally: + if 'cursor' in locals(): + cursor.close() + if 'conn' in locals(): + conn.close() + +@app.route("/v1/pizza", methods=["POST"]) +def create_pizza(): + try: + data = request.get_json() + name = data.get("name") + size = data.get("size") + price = data.get("price") + + if not all([name, size, price]): + return error_response(400, "Missing required fields") + + conn = get_db_connection() + cursor = conn.cursor(dictionary=True) + + cursor.execute( + "INSERT INTO pizza (name, size, price) VALUES (%s, %s, %s)", + (name, size, price) + ) + conn.commit() + + new_id = cursor.lastrowid + cursor.execute("SELECT * FROM pizza WHERE id = %s", (new_id,)) + new_pizza = cursor.fetchone() + + return success_response(new_pizza, 201, "Pizza created successfully") + + except Exception as e: + return error_response(500, str(e)) + finally: + if 'cursor' in locals(): + cursor.close() + if 'conn' in locals(): + conn.close() + +@app.route("/v1/pizza/", methods=["PATCH"]) +def update_pizza(id): + try: + data = request.get_json() + fields = [] + params = [] + + for key in ["name", "size", "price"]: + if key in data: + fields.append(f"{key} = %s") + params.append(data[key]) + + if not fields: + return error_response(400, "No fields to update") + + params.append(id) + + conn = get_db_connection() + cursor = conn.cursor(dictionary=True) + + cursor.execute(f"UPDATE pizza SET {', '.join(fields)} WHERE id = %s", params) + conn.commit() + + cursor.execute("SELECT * FROM pizza WHERE id = %s", (id,)) + updated_pizza = cursor.fetchone() + + if not updated_pizza: + return error_response(404, "Pizza not found") + + return success_response(updated_pizza, 200, "Pizza updated successfully") + + except Exception as e: + return error_response(500, str(e)) + finally: + if 'cursor' in locals(): + cursor.close() + if 'conn' in locals(): + conn.close() + +@app.route("/v1/pizza/", methods=["DELETE"]) +def delete_pizza(id): + try: + conn = get_db_connection() + cursor = conn.cursor() + + cursor.execute("DELETE FROM pizza WHERE id = %s", (id,)) + conn.commit() + + if cursor.rowcount == 0: + return error_response(404, "Pizza not found") + + return success_response(None, 204, "Pizza deleted successfully") + + except Exception as e: + return error_response(500, str(e)) + finally: + if 'cursor' in locals(): + cursor.close() + if 'conn' in locals(): + conn.close() + +if __name__ == "__main__": + app.run(debug=True) \ No newline at end of file diff --git a/insert_pizza_data.py b/insert_pizza_data.py new file mode 100644 index 0000000..c4e6aae --- /dev/null +++ b/insert_pizza_data.py @@ -0,0 +1,63 @@ +import pandas as pd +import mysql.connector +from mysql.connector import errorcode + +# 資料庫連線資訊 +DB_HOST = "mysql.theaken.com" +DB_PORT = 33306 +DB_NAME = "db_A018" +DB_USER = "A018" +DB_PASSWORD = "4MQYkJRYtyLE" + +# Excel 檔案路徑 +EXCEL_FILE = "c:\\AI_Program\\C0908\\Data\\pizza.xlsx" + +def insert_data_to_db(): + try: + # 讀取 Excel 檔案 + data = pd.read_excel(EXCEL_FILE) + + # 檢查欄位名稱是否正確 + required_columns = ['name', 'size', 'price'] + for column in required_columns: + if column not in data.columns: + raise ValueError(f"Excel 檔案缺少必要欄位: {column}") + + # 建立資料庫連線 + conn = mysql.connector.connect( + host=DB_HOST, + port=DB_PORT, + user=DB_USER, + password=DB_PASSWORD, + database=DB_NAME + ) + cursor = conn.cursor() + + # 插入資料到 pizza 資料表,ID 自動生成 + for index, row in data.iterrows(): + insert_query = ( + "INSERT INTO pizza (name, size, price) " + "VALUES (%s, %s, %s)" + ) + cursor.execute(insert_query, (row['name'], row['size'], row['price'])) + + conn.commit() + print("資料插入成功!") + + except mysql.connector.Error as err: + if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: + print("使用者名稱或密碼錯誤") + elif err.errno == errorcode.ER_BAD_DB_ERROR: + print("資料庫不存在") + else: + print(err) + except Exception as e: + print(f"處理資料時發生錯誤: {e}") + finally: + if 'cursor' in locals(): + cursor.close() + if 'conn' in locals(): + conn.close() + +if __name__ == "__main__": + insert_data_to_db() \ No newline at end of file diff --git a/read_pizza_excel.py b/read_pizza_excel.py new file mode 100644 index 0000000..19e2802 --- /dev/null +++ b/read_pizza_excel.py @@ -0,0 +1,17 @@ +import pandas as pd + +# 讀取 Excel 檔案 +file_path = "c:\\AI_Program\\C0908\\Data\\pizza.xlsx" + +def read_excel(): + try: + # 使用 pandas 讀取 Excel + data = pd.read_excel(file_path) + print("資料內容:") + print(data.head()) + return data + except Exception as e: + print(f"讀取 Excel 檔案時發生錯誤: {e}") + +if __name__ == "__main__": + read_excel() \ No newline at end of file diff --git a/test_db_connection.py b/test_db_connection.py new file mode 100644 index 0000000..121946b --- /dev/null +++ b/test_db_connection.py @@ -0,0 +1,53 @@ +import mysql.connector +from mysql.connector import errorcode + +# 資料庫連線資訊 +DB_HOST = "mysql.theaken.com" +DB_PORT = 33306 +DB_NAME = "db_A018" +DB_USER = "A018" +DB_PASSWORD = "4MQYkJRYtyLE" + +def create_table(): + try: + # 建立資料庫連線 + conn = mysql.connector.connect( + host=DB_HOST, + port=DB_PORT, + user=DB_USER, + password=DB_PASSWORD, + database=DB_NAME + ) + cursor = conn.cursor() + + # 如果資料表已存在,先刪除 + cursor.execute("DROP TABLE IF EXISTS pizza") + + # 建立資料表 + create_table_query = ( + "CREATE TABLE pizza (" + " id INT AUTO_INCREMENT PRIMARY KEY," + " name VARCHAR(50)," + " size VARCHAR(50)," + " price INT" + ")" + ) + cursor.execute(create_table_query) + + print("資料表建立成功!") + + except mysql.connector.Error as err: + if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: + print("使用者名稱或密碼錯誤") + elif err.errno == errorcode.ER_BAD_DB_ERROR: + print("資料庫不存在") + else: + print(err) + finally: + if 'cursor' in locals(): + cursor.close() + if 'conn' in locals(): + conn.close() + +if __name__ == "__main__": + create_table() \ No newline at end of file diff --git a/新文字文件.txt b/新文字文件.txt new file mode 100644 index 0000000..e69de29