Initial commit
This commit is contained in:
5
.env
Normal file
5
.env
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
DB_HOST=mysql.theaken.com
|
||||||
|
DB_PORT=33306
|
||||||
|
DB_NAME=db_A021
|
||||||
|
DB_USER=A021
|
||||||
|
DB_PASSWORD=wJk1O5qtP7pf
|
35
20250908_AI Prompt.txt
Normal file
35
20250908_AI Prompt.txt
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
請執行hw3_Products_lowMargin.md prompt 內容
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
您一是資深程式設計師,請根據以下需求幫我產生一段 Python 程式碼,能夠連線到資料庫一個 pizzas table及新增10筆資料。
|
||||||
|
資料庫資訊:請參考Z:\E\AI\AI_Coding\DB>.env。
|
||||||
|
需求:
|
||||||
|
1.create pizzas TABLE,pizzas table 的欄位有:name(名稱)、size(尺寸)、price(價格)
|
||||||
|
2.請您在產生10筆模擬資料新增到 pizzas table。
|
||||||
|
3.執行成功後,印出「pizzas 的模擬資料!」。
|
||||||
|
4.請將產生出的 Python 儲存於 Z:\E\AI\AI_Coding\20250908> 路徑下。
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
請產生一支可直接執行的 Flask API 伺服器,需求:
|
||||||
|
- 使用 mysql.connector 連線
|
||||||
|
|
||||||
|
資料庫資訊:請參考Z:\E\AI\AI_Coding\DB>.env。
|
||||||
|
TABLE = users
|
||||||
|
|
||||||
|
- 路由:
|
||||||
|
- GET /v1/users:支援 ?min_age、?max_age、?page、?limit,要多回傳 {meta}
|
||||||
|
- GET /v1/users/<id>:找不到回 404
|
||||||
|
- POST /v1/users:接收 JSON {name,email,age},欄位驗證,成功回 201 並回新資料
|
||||||
|
- PATCH /v1/users/<id>:可更新任一欄位(name/email/age),成功回 200 回更新後資料
|
||||||
|
- DELETE /v1/users/<id>:成功回 204
|
||||||
|
|
||||||
|
- 所有寫入請用參數化查詢避免 SQL 注入
|
||||||
|
- 統一格式 { status,code,message,data }
|
||||||
|
- 統一錯誤格式 {status:"error", code, message}
|
||||||
|
- 啟用 CORS(允許本機前端)
|
||||||
|
|
||||||
|
|
||||||
|
|
60
create_and_insert_pizzas.py
Normal file
60
create_and_insert_pizzas.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import mysql.connector
|
||||||
|
from mysql.connector import Error
|
||||||
|
import random
|
||||||
|
|
||||||
|
# 資料庫連線資訊
|
||||||
|
db_config = {
|
||||||
|
'host': 'mysql.theaken.com',
|
||||||
|
'port': 33306,
|
||||||
|
'database': 'db_A021',
|
||||||
|
'user': 'A021',
|
||||||
|
'password': 'wJk1O5qtP7pf'
|
||||||
|
}
|
||||||
|
|
||||||
|
# 披薩名稱列表
|
||||||
|
pizza_names = [
|
||||||
|
'瑪格麗特', '夏威夷', '海鮮總匯', '燻雞蘑菇', '蔬菜總匯',
|
||||||
|
'德式香腸', '四種起司', '韓式泡菜', '泰式酸辣', 'BBQ烤肉'
|
||||||
|
]
|
||||||
|
|
||||||
|
# 披薩尺寸列表
|
||||||
|
pizza_sizes = ['S', 'M', 'L', 'XL']
|
||||||
|
|
||||||
|
def create_and_insert_pizzas():
|
||||||
|
try:
|
||||||
|
# 建立資料庫連線
|
||||||
|
connection = mysql.connector.connect(**db_config)
|
||||||
|
cursor = connection.cursor()
|
||||||
|
|
||||||
|
# 創建pizzas表
|
||||||
|
cursor.execute("""
|
||||||
|
CREATE TABLE IF NOT EXISTS pizzas (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
name VARCHAR(50) NOT NULL,
|
||||||
|
size VARCHAR(10) NOT NULL,
|
||||||
|
price INT NOT NULL
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
|
||||||
|
# 新增10筆披薩資料
|
||||||
|
for i in range(10):
|
||||||
|
name = random.choice(pizza_names)
|
||||||
|
size = random.choice(pizza_sizes)
|
||||||
|
price = random.randint(100, 500)
|
||||||
|
|
||||||
|
query = "INSERT INTO pizzas (name, size, price) VALUES (%s, %s, %s)"
|
||||||
|
cursor.execute(query, (name, size, price))
|
||||||
|
|
||||||
|
# 提交交易
|
||||||
|
connection.commit()
|
||||||
|
print("pizzas 的模擬資料!")
|
||||||
|
|
||||||
|
except Error as e:
|
||||||
|
print(f"資料庫錯誤: {e}")
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
create_and_insert_pizzas()
|
231
pizza_api.py
Normal file
231
pizza_api.py
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
from flask import Flask, request, jsonify
|
||||||
|
from flask_cors import CORS
|
||||||
|
import mysql.connector
|
||||||
|
from mysql.connector import Error
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
CORS(app)
|
||||||
|
|
||||||
|
# 資料庫連線資訊
|
||||||
|
db_config = {
|
||||||
|
'host': 'mysql.theaken.com',
|
||||||
|
'port': 33306,
|
||||||
|
'database': 'db_A021',
|
||||||
|
'user': 'A021',
|
||||||
|
'password': 'wJk1O5qtP7pf'
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_db_connection():
|
||||||
|
try:
|
||||||
|
connection = mysql.connector.connect(**db_config)
|
||||||
|
return connection
|
||||||
|
except Error as e:
|
||||||
|
print(f"資料庫連線錯誤: {e}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
@app.route('/v1/pizzas', methods=['GET'])
|
||||||
|
def get_pizzas():
|
||||||
|
min_id = request.args.get('min_id', type=int)
|
||||||
|
max_id = request.args.get('max_id', type=int)
|
||||||
|
page = request.args.get('page', default=1, type=int)
|
||||||
|
limit = request.args.get('limit', default=10, type=int)
|
||||||
|
offset = (page - 1) * limit
|
||||||
|
|
||||||
|
connection = get_db_connection()
|
||||||
|
if not connection:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": "資料庫連線失敗"}), 500
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
|
# 基礎查詢
|
||||||
|
query = "SELECT * FROM pizzas WHERE 1=1"
|
||||||
|
params = []
|
||||||
|
|
||||||
|
# 添加篩選條件
|
||||||
|
if min_id is not None:
|
||||||
|
query += " AND id >= %s"
|
||||||
|
params.append(min_id)
|
||||||
|
if max_id is not None:
|
||||||
|
query += " AND id <= %s"
|
||||||
|
params.append(max_id)
|
||||||
|
|
||||||
|
# 計算總數
|
||||||
|
count_query = "SELECT COUNT(*) as total FROM (" + query + ") as t"
|
||||||
|
cursor.execute(count_query, params)
|
||||||
|
total = cursor.fetchone()['total']
|
||||||
|
|
||||||
|
# 添加分頁
|
||||||
|
query += " LIMIT %s OFFSET %s"
|
||||||
|
params.extend([limit, offset])
|
||||||
|
|
||||||
|
cursor.execute(query, params)
|
||||||
|
pizzas = cursor.fetchall()
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
"total": total,
|
||||||
|
"page": page,
|
||||||
|
"limit": limit,
|
||||||
|
"has_next": (page * limit) < total
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"status": "success",
|
||||||
|
"code": 200,
|
||||||
|
"message": "",
|
||||||
|
"data": pizzas,
|
||||||
|
"meta": meta
|
||||||
|
})
|
||||||
|
except Error as e:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": str(e)}), 500
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
@app.route('/v1/pizzas/<int:pizza_id>', methods=['GET'])
|
||||||
|
def get_pizza(pizza_id):
|
||||||
|
connection = get_db_connection()
|
||||||
|
if not connection:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": "資料庫連線失敗"}), 500
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
cursor.execute("SELECT * FROM pizzas WHERE id = %s", (pizza_id,))
|
||||||
|
pizza = cursor.fetchone()
|
||||||
|
|
||||||
|
if not pizza:
|
||||||
|
return jsonify({"status": "error", "code": 404, "message": "披薩不存在"}), 404
|
||||||
|
|
||||||
|
return jsonify({"status": "success", "code": 200, "message": "", "data": pizza})
|
||||||
|
except Error as e:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": str(e)}), 500
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
@app.route('/v1/pizzas', methods=['POST'])
|
||||||
|
def create_pizza():
|
||||||
|
data = request.get_json()
|
||||||
|
|
||||||
|
# 驗證必要欄位
|
||||||
|
if not all(key in data for key in ['name', 'size', 'price']):
|
||||||
|
return jsonify({"status": "error", "code": 400, "message": "缺少必要欄位: name, size, price"}), 400
|
||||||
|
|
||||||
|
connection = get_db_connection()
|
||||||
|
if not connection:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": "資料庫連線失敗"}), 500
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
query = "INSERT INTO pizzas (name, size, price) VALUES (%s, %s, %s)"
|
||||||
|
cursor.execute(query, (data['name'], data['size'], data['price']))
|
||||||
|
connection.commit()
|
||||||
|
|
||||||
|
# 獲取新建立的披薩
|
||||||
|
pizza_id = cursor.lastrowid
|
||||||
|
cursor.execute("SELECT * FROM pizzas WHERE id = %s", (pizza_id,))
|
||||||
|
new_pizza = cursor.fetchone()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"status": "success",
|
||||||
|
"code": 201,
|
||||||
|
"message": "披薩建立成功",
|
||||||
|
"data": new_pizza
|
||||||
|
}), 201
|
||||||
|
except Error as e:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": str(e)}), 500
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
@app.route('/v1/pizzas/<int:pizza_id>', methods=['PATCH'])
|
||||||
|
def update_pizza(pizza_id):
|
||||||
|
# 從URL參數獲取要更新的欄位
|
||||||
|
update_name = request.args.get('name')
|
||||||
|
update_size = request.args.get('size')
|
||||||
|
update_price = request.args.get('price', type=float)
|
||||||
|
|
||||||
|
connection = get_db_connection()
|
||||||
|
if not connection:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": "資料庫連線失敗"}), 500
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor(dictionary=True)
|
||||||
|
|
||||||
|
# 檢查披薩是否存在
|
||||||
|
cursor.execute("SELECT * FROM pizzas WHERE id = %s", (pizza_id,))
|
||||||
|
pizza = cursor.fetchone()
|
||||||
|
if not pizza:
|
||||||
|
return jsonify({"status": "error", "code": 404, "message": "披薩不存在"}), 404
|
||||||
|
|
||||||
|
# 構建更新語句
|
||||||
|
set_clauses = []
|
||||||
|
params = []
|
||||||
|
|
||||||
|
if update_name is not None:
|
||||||
|
set_clauses.append("name = %s")
|
||||||
|
params.append(update_name)
|
||||||
|
if update_size is not None:
|
||||||
|
set_clauses.append("size = %s")
|
||||||
|
params.append(update_size)
|
||||||
|
if update_price is not None:
|
||||||
|
set_clauses.append("price = %s")
|
||||||
|
params.append(update_price)
|
||||||
|
|
||||||
|
# 如果沒有提供任何可更新參數
|
||||||
|
if not set_clauses:
|
||||||
|
return jsonify({"status": "error", "code": 400, "message": "至少需要提供一個更新參數: name, size, price"}), 400
|
||||||
|
|
||||||
|
query = "UPDATE pizzas SET " + ", ".join(set_clauses) + " WHERE id = %s"
|
||||||
|
params.append(pizza_id)
|
||||||
|
|
||||||
|
cursor.execute(query, params)
|
||||||
|
connection.commit()
|
||||||
|
|
||||||
|
# 獲取更新後的披薩
|
||||||
|
cursor.execute("SELECT * FROM pizzas WHERE id = %s", (pizza_id,))
|
||||||
|
updated_pizza = cursor.fetchone()
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"status": "success",
|
||||||
|
"code": 200,
|
||||||
|
"message": "披薩更新成功",
|
||||||
|
"data": updated_pizza
|
||||||
|
})
|
||||||
|
except Error as e:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": str(e)}), 500
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
@app.route('/v1/pizzas/<int:pizza_id>', methods=['DELETE'])
|
||||||
|
def delete_pizza(pizza_id):
|
||||||
|
connection = get_db_connection()
|
||||||
|
if not connection:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": "資料庫連線失敗"}), 500
|
||||||
|
|
||||||
|
try:
|
||||||
|
cursor = connection.cursor()
|
||||||
|
|
||||||
|
# 檢查披薩是否存在
|
||||||
|
cursor.execute("SELECT id FROM pizzas WHERE id = %s", (pizza_id,))
|
||||||
|
if not cursor.fetchone():
|
||||||
|
return jsonify({"status": "error", "code": 404, "message": "披薩不存在"}), 404
|
||||||
|
|
||||||
|
cursor.execute("DELETE FROM pizzas WHERE id = %s", (pizza_id,))
|
||||||
|
connection.commit()
|
||||||
|
|
||||||
|
return '', 204
|
||||||
|
except Error as e:
|
||||||
|
return jsonify({"status": "error", "code": 500, "message": str(e)}), 500
|
||||||
|
finally:
|
||||||
|
if connection.is_connected():
|
||||||
|
cursor.close()
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(debug=True)
|
Reference in New Issue
Block a user