這個專案是一個使用 Flask 和 MySQL 建構的任務管理器應用程式。它提供了一個簡單的 RESTful API 來管理任務,演示了基本的 CRUD(建立、讀取、刪除)操作。
此應用程式非常適合了解如何使用 Docker 將 Flask 應用程式容器化並與 MySQL 資料庫連接。
from flask import Flask, request, jsonify import mysql.connector from mysql.connector import Error app = Flask(__name__) # Database connection function def get_db_connection(): try: connection = mysql.connector.connect( host="db", user="root", password="example", database="task_db" ) return connection except Error as e: return str(e) # Route for the home page @app.route('/') def home(): return "Welcome to the Task Management API! Use /tasks to interact with tasks." # Route to create a new task @app.route('/tasks', methods=['POST']) def add_task(): task_description = request.json.get('description') if not task_description: return jsonify({"error": "Task description is required"}), 400 connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("INSERT INTO tasks (description) VALUES (%s)", (task_description,)) connection.commit() task_id = cursor.lastrowid cursor.close() connection.close() return jsonify({"message": "Task added successfully", "task_id": task_id}), 201 # Route to get all tasks @app.route('/tasks', methods=['GET']) def get_tasks(): connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("SELECT id, description FROM tasks") tasks = cursor.fetchall() cursor.close() connection.close() task_list = [{"id": task[0], "description": task[1]} for task in tasks] return jsonify(task_list), 200 # Route to delete a task by ID @app.route('/tasks/<int:task_id>', methods=['DELETE']) def delete_task(task_id): connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("DELETE FROM tasks WHERE id = %s", (task_id,)) connection.commit() cursor.close() connection.close() return jsonify({"message": "Task deleted successfully"}), 200 if __name__ == "__main__": app.run(host='0.0.0.0')
建立名為 init-db.sql 的 MySQL 腳本來設定資料庫和任務表:
要建立 init-db.sql 腳本,請依照下列步驟操作:
在專案目錄中建立一個新的檔案:
導覽至專案資料夾並建立一個名為 init-db.sql
的新文件
新增 SQL 指令來設定資料庫和任務表:
在文字編輯器中開啟 init-db.sql 並新增下列 SQL 指令:
CREATE DATABASE IF NOT EXISTS task_db; USE task_db; CREATE TABLE IF NOT EXISTS tasks ( id INT AUTO_INCREMENT PRIMARY KEY, description VARCHAR(255) NOT NULL );
我將檔案儲存為init-db.sql 位於我的docker-compose.yml 所在的專案資料夾中.
在 docker-compose.yml 中:
在我的 docker-compose.yml 檔案中,我有指向此腳本的捲配置。
下面是docker-compose.yml檔案
docker-compose.yml:
version: '3' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example MYSQL_DATABASE: task_db ports: - "3306:3306" volumes: - db_data:/var/lib/mysql - ./init-db.sql:/docker-entrypoint-initdb.d/init-db.sql web: build: . ports: - "5000:5000" depends_on: - db environment: FLASK_ENV: development volumes: - .:/app volumes: db_data:
此配置確保當MySQL 容器啟動時,它將執行init-db.sql 腳本來設定task_db 資料庫並建立tasks 表。
注意:docker-entrypoint-initdb.d/目錄被MySQL容器用來執行.sql 容器初始啟動期間的腳本。 解釋:
2。服務:
資料庫:
網頁:
定義 Flask 應用程式的建置指令:
from flask import Flask, request, jsonify import mysql.connector from mysql.connector import Error app = Flask(__name__) # Database connection function def get_db_connection(): try: connection = mysql.connector.connect( host="db", user="root", password="example", database="task_db" ) return connection except Error as e: return str(e) # Route for the home page @app.route('/') def home(): return "Welcome to the Task Management API! Use /tasks to interact with tasks." # Route to create a new task @app.route('/tasks', methods=['POST']) def add_task(): task_description = request.json.get('description') if not task_description: return jsonify({"error": "Task description is required"}), 400 connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("INSERT INTO tasks (description) VALUES (%s)", (task_description,)) connection.commit() task_id = cursor.lastrowid cursor.close() connection.close() return jsonify({"message": "Task added successfully", "task_id": task_id}), 201 # Route to get all tasks @app.route('/tasks', methods=['GET']) def get_tasks(): connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("SELECT id, description FROM tasks") tasks = cursor.fetchall() cursor.close() connection.close() task_list = [{"id": task[0], "description": task[1]} for task in tasks] return jsonify(task_list), 200 # Route to delete a task by ID @app.route('/tasks/<int:task_id>', methods=['DELETE']) def delete_task(task_id): connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("DELETE FROM tasks WHERE id = %s", (task_id,)) connection.commit() cursor.close() connection.close() return jsonify({"message": "Task deleted successfully"}), 200 if __name__ == "__main__": app.run(host='0.0.0.0')
這個 Dockerfile 為 Flask 應用程式設定了一個輕量級的 Python 環境:
1。基礎鏡像: 使用 python:3.9-slim 來實現最短的 Python 運行時間。
工作目錄:將 /app 設定為工作目錄。
2。依賴項:複製requirements.txt並透過pip安裝依賴項。
3。工具安裝: 安裝 wait-for-it 以檢查服務準備。
4。應用程式程式碼: 將所有應用程式程式碼複製到容器中。
5。啟動指令: 執行 wait-for-it 以確保 MySQL DB (db:3306) 在啟動 app.py 之前準備就緒。
此requirements.txt 指定Python 專案需要Flask 框架 來建立Web 應用程式和mysql-connector-python
from flask import Flask, request, jsonify import mysql.connector from mysql.connector import Error app = Flask(__name__) # Database connection function def get_db_connection(): try: connection = mysql.connector.connect( host="db", user="root", password="example", database="task_db" ) return connection except Error as e: return str(e) # Route for the home page @app.route('/') def home(): return "Welcome to the Task Management API! Use /tasks to interact with tasks." # Route to create a new task @app.route('/tasks', methods=['POST']) def add_task(): task_description = request.json.get('description') if not task_description: return jsonify({"error": "Task description is required"}), 400 connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("INSERT INTO tasks (description) VALUES (%s)", (task_description,)) connection.commit() task_id = cursor.lastrowid cursor.close() connection.close() return jsonify({"message": "Task added successfully", "task_id": task_id}), 201 # Route to get all tasks @app.route('/tasks', methods=['GET']) def get_tasks(): connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("SELECT id, description FROM tasks") tasks = cursor.fetchall() cursor.close() connection.close() task_list = [{"id": task[0], "description": task[1]} for task in tasks] return jsonify(task_list), 200 # Route to delete a task by ID @app.route('/tasks/<int:task_id>', methods=['DELETE']) def delete_task(task_id): connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("DELETE FROM tasks WHERE id = %s", (task_id,)) connection.commit() cursor.close() connection.close() return jsonify({"message": "Task deleted successfully"}), 200 if __name__ == "__main__": app.run(host='0.0.0.0')建立所有檔案後,下一步是建置並執行服務,使用以下命令來建置和執行服務。
CREATE DATABASE IF NOT EXISTS task_db; USE task_db; CREATE TABLE IF NOT EXISTS tasks ( id INT AUTO_INCREMENT PRIMARY KEY, description VARCHAR(255) NOT NULL );要以分離模式運行服務,我使用以下命令而不是
docker-compose up
version: '3' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example MYSQL_DATABASE: task_db ports: - "3306:3306" volumes: - db_data:/var/lib/mysql - ./init-db.sql:/docker-entrypoint-initdb.d/init-db.sql web: build: . ports: - "5000:5000" depends_on: - db environment: FLASK_ENV: development volumes: - .:/app volumes: db_data:當我想停止服務時,我使用指令
FROM python:3.9-slim WORKDIR /app # Install dependencies COPY requirements.txt . RUN pip install -r requirements.txt # Install wait-for-it tool# RUN apt-get update && apt-get install -y wait-for-it #Copy the application code> COPY . . # Use wait-for-it to wait for DB and start the Flask app CMD ["wait-for-it", "db:3306", "--", "python", "app.py"]現在,一旦服務處於運作狀態,請執行指令
Flask mysql-connector-python確保容器正在運作
現在是時候檢查服務 API 以確保它們按預期工作了。
測試項目
運行上述命令後,我能夠在瀏覽器上存取該應用程序,如下圖所示。
您可以使用 Postman 或 curl 來測試 /tasks 端點的 POST、GET 和 DELETE 操作。在這種情況下,我將使用curl。
捲曲命令:
docker-compose build docker-compose up
請注意,每當您在瀏覽器上執行 http://localhost:5000/tasks 時,它都會顯示您已新增的所有任務,如新增任務中所述。
docker-compose up -d這將向您的 Flask 應用程式發送帶有任務描述的 POST 請求。如果任務新增成功,您應該會收到以下回應:
docker-compose down檢查瀏覽器的網路標籤或日誌以驗證 POST 請求是否正確發出。
我運行了該命令幾次,並自訂了「簡單任務」部分以產生不同的輸出,這是我運行的命令,輸出可以在下圖中看到。
docker ps
from flask import Flask, request, jsonify import mysql.connector from mysql.connector import Error app = Flask(__name__) # Database connection function def get_db_connection(): try: connection = mysql.connector.connect( host="db", user="root", password="example", database="task_db" ) return connection except Error as e: return str(e) # Route for the home page @app.route('/') def home(): return "Welcome to the Task Management API! Use /tasks to interact with tasks." # Route to create a new task @app.route('/tasks', methods=['POST']) def add_task(): task_description = request.json.get('description') if not task_description: return jsonify({"error": "Task description is required"}), 400 connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("INSERT INTO tasks (description) VALUES (%s)", (task_description,)) connection.commit() task_id = cursor.lastrowid cursor.close() connection.close() return jsonify({"message": "Task added successfully", "task_id": task_id}), 201 # Route to get all tasks @app.route('/tasks', methods=['GET']) def get_tasks(): connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("SELECT id, description FROM tasks") tasks = cursor.fetchall() cursor.close() connection.close() task_list = [{"id": task[0], "description": task[1]} for task in tasks] return jsonify(task_list), 200 # Route to delete a task by ID @app.route('/tasks/<int:task_id>', methods=['DELETE']) def delete_task(task_id): connection = get_db_connection() if isinstance(connection, str): # If connection fails return jsonify({"error": connection}), 500 cursor = connection.cursor() cursor.execute("DELETE FROM tasks WHERE id = %s", (task_id,)) connection.commit() cursor.close() connection.close() return jsonify({"message": "Task deleted successfully"}), 200 if __name__ == "__main__": app.run(host='0.0.0.0')
CREATE DATABASE IF NOT EXISTS task_db; USE task_db; CREATE TABLE IF NOT EXISTS tasks ( id INT AUTO_INCREMENT PRIMARY KEY, description VARCHAR(255) NOT NULL );
DELETE 方法透過 ID 刪除任務。
version: '3' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: example MYSQL_DATABASE: task_db ports: - "3306:3306" volumes: - db_data:/var/lib/mysql - ./init-db.sql:/docker-entrypoint-initdb.d/init-db.sql web: build: . ports: - "5000:5000" depends_on: - db environment: FLASK_ENV: development volumes: - .:/app volumes: db_data:
我執行了以下命令來刪除 ID 為 4 的任務,如下圖所示,任務 4 已被刪除。
FROM python:3.9-slim WORKDIR /app # Install dependencies COPY requirements.txt . RUN pip install -r requirements.txt # Install wait-for-it tool# RUN apt-get update && apt-get install -y wait-for-it #Copy the application code> COPY . . # Use wait-for-it to wait for DB and start the Flask app CMD ["wait-for-it", "db:3306", "--", "python", "app.py"]
使用 Flask 和 MySQL 建立任務管理器應用程式是了解 Web 服務開發、資料庫整合和 Docker 容器化基礎知識的絕佳方法。
該專案封裝了 Web 伺服器和資料庫如何協同工作以提供無縫功能。
擁抱這種學習體驗,並將其用作更深層的網路和基於雲端的開發專案的墊腳石。
以上是使用 Flask 和 MySQL 的任務管理器應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!