资讯详情

资讯详情

2小时搭建Flask+ECharts+SQLite数据可视化平台实战

你是不是也遇到过这样的困境课程设计、毕业设计或者个人项目需要一个“拿得出手”的数据分析可视化系统但时间紧、任务重不知道从何下手网上教程要么太简单要么太复杂要么就是代码跑不通今天我们用一个真实的商业场景——霸王茶姬门店销量数据分析平台来演示如何用2小时从零搭建一个功能完整、界面美观、数据动态更新的Web可视化系统。这个项目麻雀虽小五脏俱全涵盖了Python数据处理、Flask后端开发、ECharts前端可视化以及SQLite数据库操作四大核心技能点。这篇文章的核心判断是对于初学者或需要快速交付原型的开发者来说Flask ECharts SQLite 是构建轻量级数据可视化平台的最优技术组合之一。它门槛低、上手快、生态成熟能让你在极短时间内将数据处理逻辑与炫酷的图表展示无缝对接。读完本文你将能独立完成搭建一个完整的Flask Web应用骨架。使用Pandas清洗和分析模拟的销售数据。设计SQLite数据库并实现数据的增删改查。编写RESTful API接口为前端提供JSON数据。利用ECharts绘制多种交互式图表柱状图、折线图、饼图。将所有模块整合形成一个可交互的数据可视化大屏。我们直接进入正题。1. 为什么选择 Flask ECharts SQLite 这套组合拳在开始敲代码之前我们先搞清楚这套技术栈为什么适合这个场景。很多教程只教你怎么做却不告诉你为什么这么选导致你换一个项目又无从下手。Flask一个轻量级的Python Web框架。它的核心优势是“微”。你不需要像Django那样一开始就面对庞大的项目结构和复杂的配置。对于数据可视化这种“后端主要提供数据接口”的项目Flask几行代码就能启动一个服务器快速响应前端的数据请求开发效率极高。ECharts一个由百度开源的数据可视化图表库。它几乎涵盖了所有常见的图表类型配置项丰富文档极其详细并且社区活跃。更重要的是它通过简单的JavaScript配置就能生成非常专业的图表你不需要深入钻研D3.js那种底层绘图库学习成本低效果出众。SQLite一个嵌入式数据库。它不需要安装独立的数据库服务所有数据存储在一个单独的.db文件中。对于课程设计、小型项目或原型演示SQLite避免了配置MySQL或PostgreSQL的繁琐项目迁移和部署异常简单直接拷贝文件即可。PandasPython数据分析的事实标准库。我们用它来模拟、清洗和聚合数据它的DataFrame数据结构与SQL查询、JSON转换都能完美配合。它们的协作流程是Pandas处理数据 → 存入SQLite数据库 → Flask从数据库查询数据 → 通过API接口返回JSON → 前端JavaScript调用API → ECharts渲染图表。这套组合完美平衡了开发效率、学习成本、功能需求和部署复杂度是快速实现数据分析可视化的“黄金搭档”。2. 环境准备与项目初始化在开始之前请确保你的电脑已经安装了Python建议3.7及以上版本。我们将使用pip来管理所有依赖。2.1 创建项目目录与虚拟环境首先创建一个干净的项目目录并进入该目录。使用虚拟环境是一个好习惯它能隔离项目依赖避免版本冲突。# 创建项目目录 mkdir chagee_sales_dashboard cd chagee_sales_dashboard # 创建虚拟环境 (Windows) python -m venv venv # 激活虚拟环境 (Windows) venv\Scripts\activate # 创建虚拟环境 (macOS/Linux) python3 -m venv venv # 激活虚拟环境 (macOS/Linux) source venv/bin/activate激活后命令行提示符前会出现(venv)字样。2.2 安装必备依赖库我们将主要用到以下四个库。在激活的虚拟环境中执行以下命令一次性安装pip install flask pandas numpy注意numpy是pandas的依赖通常会一并安装。ECharts是前端库通过CDN引入无需Python安装。为了便于开发我们还可以安装python-dotenv来管理环境变量但本项目为简化起见暂不使用。3. 项目结构设计清晰的目录结构是项目可维护性的基础。在项目根目录下创建如下文件和文件夹chagee_sales_dashboard/ ├── app.py # Flask应用主入口 ├── data_processor.py # 数据处理与数据库操作模块 ├── database.db # SQLite数据库文件运行后自动生成 ├── static/ # 静态资源文件夹 │ └── css/ │ └── style.css # 自定义样式 └── templates/ # HTML模板文件夹 └── index.html # 主页面你可以使用以下命令快速创建mkdir -p static/css templates touch app.py data_processor.py touch static/css/style.css templates/index.html4. 核心模块一数据处理与数据库 (data_processor.py)这个模块负责所有“脏活累活”生成模拟数据、创建数据库表、插入数据、以及最重要的——提供各种数据查询函数供Flask调用。4.1 生成模拟销售数据我们使用Pandas和NumPy来模拟霸王茶姬一个季度约90天的销售数据包含日期、门店、产品品类和销售额。# data_processor.py import pandas as pd import numpy as np from datetime import datetime, timedelta import sqlite3 import os def generate_mock_data(): 生成模拟的霸王茶姬销售数据 np.random.seed(42) # 设置随机种子确保每次生成的数据一致 start_date datetime(2023, 10, 1) days 90 date_list [start_date timedelta(daysi) for i in range(days)] stores [北京国贸店, 上海静安店, 广州天河店, 深圳南山店, 成都春熙店] categories [原叶鲜奶茶, 清爽果茶, 芝士茗茶, 季节限定] data [] for single_date in date_list: for store in stores: for category in categories: # 模拟每日每店每品类的销售额加入一些随机波动和趋势 base_sale np.random.randint(200, 500) # 周末销量更高 if single_date.weekday() 5: base_sale int(base_sale * 1.5) # 不同品类有基础差异 if category 季节限定: base_sale int(base_sale * 1.3) # 加入随机噪声 sale max(100, int(base_sale np.random.normal(0, 50))) data.append({ date: single_date.strftime(%Y-%m-%d), store: store, category: category, sales: sale }) df pd.DataFrame(data) return df4.2 初始化数据库与数据表接下来我们连接SQLite数据库并创建一个sales_records表来存储这些数据。# data_processor.py (续) def init_database(db_pathdatabase.db): 初始化数据库创建表并插入模拟数据如果表不存在 conn sqlite3.connect(db_path) cursor conn.cursor() # 创建销售记录表 cursor.execute( CREATE TABLE IF NOT EXISTS sales_records ( id INTEGER PRIMARY KEY AUTOINCREMENT, date TEXT NOT NULL, store TEXT NOT NULL, category TEXT NOT NULL, sales INTEGER NOT NULL ) ) # 检查表中是否有数据没有则插入模拟数据 cursor.execute(SELECT COUNT(*) FROM sales_records) if cursor.fetchone()[0] 0: print(数据库为空正在插入模拟数据...) df generate_mock_data() df.to_sql(sales_records, conn, if_existsappend, indexFalse) print(f模拟数据插入完成共{len(df)}条记录。) else: print(数据库中已有数据跳过插入。) conn.commit() conn.close()4.3 核心数据查询函数这是后端API的“弹药库”。我们编写几个函数从不同维度聚合数据供前端图表使用。# data_processor.py (续) def get_total_sales_by_store(): 获取各门店总销售额 conn sqlite3.connect(database.db) query SELECT store, SUM(sales) as total_sales FROM sales_records GROUP BY store ORDER BY total_sales DESC df pd.read_sql_query(query, conn) conn.close() # 转换为前端ECharts需要的格式: [[店名, 销售额], ...] result df[[store, total_sales]].values.tolist() return result def get_daily_sales_trend(storeNone): 获取每日销售趋势线可筛选门店 conn sqlite3.connect(database.db) if store: query SELECT date, SUM(sales) as daily_sales FROM sales_records WHERE store ? GROUP BY date ORDER BY date df pd.read_sql_query(query, conn, params(store,)) else: query SELECT date, SUM(sales) as daily_sales FROM sales_records GROUP BY date ORDER BY date df pd.read_sql_query(query, conn) conn.close() # 格式: {dates: [2023-10-01, ...], sales: [1200, ...]} return { dates: df[date].tolist(), sales: df[daily_sales].tolist() } def get_sales_by_category(): 获取各产品品类销售额占比 conn sqlite3.connect(database.db) query SELECT category, SUM(sales) as category_sales FROM sales_records GROUP BY category ORDER BY category_sales DESC df pd.read_sql_query(query, conn) conn.close() # 格式: [{name: 品类, value: 销售额}, ...] result [{name: row[category], value: int(row[category_sales])} for _, row in df.iterrows()] return result def get_top_selling_days(limit10): 获取销量最高的几天 conn sqlite3.connect(database.db) query SELECT date, SUM(sales) as daily_sales FROM sales_records GROUP BY date ORDER BY daily_sales DESC LIMIT ? df pd.read_sql_query(query, conn, params(limit,)) conn.close() # 格式: [[日期, 销售额], ...] result df[[date, daily_sales]].values.tolist() return result至此我们的“数据引擎”就准备好了。它独立于Web框架方便单独测试和维护。5. 核心模块二Flask后端API (app.py)Flask在这里扮演“交通指挥员”的角色接收前端请求调用数据处理函数并将结果以JSON格式返回。5.1 初始化Flask应用与数据库# app.py from flask import Flask, render_template, jsonify from data_processor import init_database, get_total_sales_by_store, get_daily_sales_trend, get_sales_by_category, get_top_selling_days app Flask(__name__) # 在应用启动时初始化数据库 app.before_first_request def initialize_database(): init_database()app.before_first_request装饰器确保在处理第一个请求前数据库已经准备就绪。5.2 定义页面路由与API接口我们需要一个主页面来展示可视化大屏以及多个API接口来提供图表数据。# app.py (续) app.route(/) def index(): 渲染主页面 return render_template(index.html) # ---------- 以下是数据API接口 ---------- app.route(/api/total_sales_by_store) def api_total_sales_by_store(): API: 各门店总销售额 data get_total_sales_by_store() return jsonify({data: data}) app.route(/api/daily_sales_trend) def api_daily_sales_trend(): API: 总销售趋势可接受门店参数 store request.args.get(store, defaultNone, typestr) data get_daily_sales_trend(store) return jsonify(data) app.route(/api/sales_by_category) def api_sales_by_category(): API: 品类销售占比 data get_sales_by_category() return jsonify({data: data}) app.route(/api/top_selling_days) def api_top_selling_days(): API: 销量最高日期TOP10 data get_top_selling_days() return jsonify({data: data}) if __name__ __main__: # debugTrue 便于开发生产环境务必关闭 app.run(debugTrue, port5000)注意我们需要导入request来获取URL参数。请在文件顶部添加导入from flask import request。现在后端部分已经完成。运行python app.py访问http://127.0.0.1:5000你会看到一个空白页面但后端API已经在工作了。你可以尝试直接访问http://127.0.0.1:5000/api/total_sales_by_store来测试应该能看到返回的JSON数据。6. 核心模块三前端可视化页面 (templates/index.html)这是项目的“门面”。我们将使用ECharts来绘制图表并用一点CSS让页面更美观。6.1 基础HTML结构与资源引入我们使用Bootstrap 5快速搭建响应式布局并通过CDN引入ECharts。!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title霸王茶姬门店销量数据分析平台/title !-- Bootstrap 5 CSS -- link hrefhttps://cdn.jsdelivr.net/npm/bootstrap5.1.3/dist/css/bootstrap.min.css relstylesheet !-- ECharts -- script srchttps://cdn.jsdelivr.net/npm/echarts5.4.3/dist/echarts.min.js/script !-- 自定义CSS -- link relstylesheet href{{ url_for(static, filenamecss/style.css) }} /head body div classcontainer-fluid py-4 header classtext-center mb-5 h1 classdisplay-4 fw-bold text-primary 霸王茶姬门店销量数据分析平台/h1 p classlead text-muted基于 Flask ECharts SQLite 构建 | 数据动态更新 | 多维度可视化/p hr classmy-4 /header div classrow mb-4 !-- 图表选择器或说明区域 -- div classcol-12 div classalert alert-info h5i classbi bi-info-circle/i 平台说明/h5 p classmb-0本平台展示了模拟的霸王茶姬90天销售数据。所有图表数据均通过Flask API实时从SQLite数据库获取并利用ECharts渲染。点击图表可查看详细数据提示。/p /div /div /div !-- 第一行柱状图 趋势图 -- div classrow mb-4 div classcol-lg-6 col-md-12 mb-4 div classcard shadow h-100 div classcard-header bg-primary text-white h5 classcard-title mb-0i classbi bi-bar-chart-fill/i 各门店总销售额排行/h5 /div div classcard-body div idchartStoreSales stylewidth: 100%; height: 400px;/div /div /div /div div classcol-lg-6 col-md-12 mb-4 div classcard shadow h-100 div classcard-header bg-success text-white h5 classcard-title mb-0i classbi bi-graph-up/i 门店销售趋势分析/h5 /div div classcard-body div classmb-3 label forstoreSelect classform-label选择门店查看趋势/label select classform-select idstoreSelect option value全部门店/option !-- 选项将通过JS动态填充 -- /select /div div idchartSalesTrend stylewidth: 100%; height: 350px;/div /div /div /div /div !-- 第二行饼图 排行榜 -- div classrow div classcol-lg-6 col-md-12 mb-4 div classcard shadow h-100 div classcard-header bg-warning text-dark h5 classcard-title mb-0i classbi bi-pie-chart-fill/i 产品品类销售额占比/h5 /div div classcard-body div idchartCategorySales stylewidth: 100%; height: 400px;/div /div /div /div div classcol-lg-6 col-md-12 mb-4 div classcard shadow h-100 div classcard-header bg-danger text-white h5 classcard-title mb-0i classbi bi-trophy-fill/i 单日销量TOP10排行榜/h5 /div div classcard-body div idchartTopDays stylewidth: 100%; height: 400px;/div /div /div /div /div footer classmt-5 pt-4 border-top text-center text-muted p课程设计实战项目 | Python数据分析与可视化 | 技术栈Flask, Pandas, SQLite, ECharts, Bootstrap/p p classsmall数据为模拟生成仅用于演示目的。/p /footer /div !-- Bootstrap JS Bundle -- script srchttps://cdn.jsdelivr.net/npm/bootstrap5.1.3/dist/js/bootstrap.bundle.min.js/script !-- 自定义JavaScript -- script src{{ url_for(static, filenamejs/main.js) }}/script /body /html6.2 自定义样式 (static/css/style.css)简单的样式美化让页面更清爽。/* static/css/style.css */ body { background-color: #f8f9fa; font-family: Segoe UI, Tahoma, Geneva, Verdana, sans-serif; } .card { border: none; border-radius: 15px; transition: transform 0.2s; } .card:hover { transform: translateY(-5px); } .card-header { border-radius: 15px 15px 0 0 !important; font-weight: 600; } #chartStoreSales, #chartSalesTrend, #chartCategorySales, #chartTopDays { border-radius: 10px; }6.3 核心JavaScript图表逻辑 (static/js/main.js)这是前端的“大脑”负责从Flask API获取数据并初始化、更新ECharts图表。// static/js/main.js // 确保在创建目录和文件 // mkdir -p static/js // touch static/js/main.js document.addEventListener(DOMContentLoaded, function() { // 1. 初始化所有图表容器 const storeSalesChart echarts.init(document.getElementById(chartStoreSales)); const salesTrendChart echarts.init(document.getElementById(chartSalesTrend)); const categorySalesChart echarts.init(document.getElementById(chartCategorySales)); const topDaysChart echarts.init(document.getElementById(chartTopDays)); // 2. 定义图表配置先定义空配置数据通过API填充 const storeSalesOption { title: { text: , left: center }, tooltip: { trigger: axis, axisPointer: { type: shadow } }, grid: { left: 3%, right: 4%, bottom: 3%, containLabel: true }, xAxis: { type: value, name: 销售额元 }, yAxis: { type: category, data: [] }, // 数据从API获取 series: [{ name: 销售额, type: bar, data: [], itemStyle: { color: #5470c6 } }] }; const salesTrendOption { title: { text: 销售趋势图, left: center }, tooltip: { trigger: axis }, grid: { left: 3%, right: 4%, bottom: 3%, containLabel: true }, xAxis: { type: category, boundaryGap: false, data: [] }, yAxis: { type: value, name: 销售额元 }, series: [{ name: 日销售额, type: line, smooth: true, data: [], lineStyle: { width: 3 }, itemStyle: { color: #91cc75 } }] }; const categorySalesOption { title: { text: 品类销售占比, left: center }, tooltip: { trigger: item, formatter: {a} br/{b}: {c} ({d}%) }, legend: { orient: vertical, left: left }, series: [ { name: 销售额, type: pie, radius: 50%, data: [], // 数据从API获取 emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: rgba(0, 0, 0, 0.5) } } } ] }; const topDaysOption { title: { text: 单日销量TOP10, left: center }, tooltip: { trigger: axis, axisPointer: { type: shadow } }, grid: { left: 3%, right: 4%, bottom: 3%, containLabel: true }, xAxis: { type: category, data: [], axisLabel: { rotate: 45 } }, yAxis: { type: value, name: 销售额元 }, series: [{ name: 销售额, type: bar, data: [], itemStyle: { color: #ee6666 } }] }; // 3. 定义获取数据的函数 function fetchDataAndRender() { // 3.1 获取门店销售额排行数据 fetch(/api/total_sales_by_store) .then(response response.json()) .then(data { const chartData data.data; // [[店名, 销售额], ...] const storeNames chartData.map(item item[0]); const salesValues chartData.map(item item[1]); storeSalesOption.yAxis.data storeNames; storeSalesOption.series[0].data salesValues; storeSalesChart.setOption(storeSalesOption); // 动态填充门店选择下拉框 const storeSelect document.getElementById(storeSelect); // 清空现有选项除了第一个“全部门店” while (storeSelect.options.length 1) { storeSelect.remove(1); } storeNames.forEach(store { const option document.createElement(option); option.value store; option.textContent store; storeSelect.appendChild(option); }); }); // 3.2 获取总销售趋势数据初始加载全部 fetch(/api/daily_sales_trend) .then(response response.json()) .then(data { salesTrendOption.xAxis.data data.dates; salesTrendOption.series[0].data data.sales; salesTrendChart.setOption(salesTrendOption); }); // 3.3 获取品类销售占比数据 fetch(/api/sales_by_category) .then(response response.json()) .then(data { categorySalesOption.series[0].data data.data; categorySalesChart.setOption(categorySalesOption); }); // 3.4 获取单日销量TOP10数据 fetch(/api/top_selling_days) .then(response response.json()) .then(data { const chartData data.data; // [[日期, 销售额], ...] const dates chartData.map(item item[0]); const sales chartData.map(item item[1]); topDaysOption.xAxis.data dates; topDaysOption.series[0].data sales; topDaysChart.setOption(topDaysOption); }); } // 4. 页面加载完成后首次获取数据并渲染图表 fetchDataAndRender(); // 5. 为门店选择下拉框添加事件监听器实现图表联动 document.getElementById(storeSelect).addEventListener(change, function() { const selectedStore this.value; let url /api/daily_sales_trend; if (selectedStore) { url ?store${encodeURIComponent(selectedStore)}; } fetch(url) .then(response response.json()) .then(data { salesTrendOption.title.text selectedStore ? ${selectedStore}销售趋势 : 全部门店销售趋势; salesTrendOption.xAxis.data data.dates; salesTrendOption.series[0].data data.sales; salesTrendChart.setOption(salesTrendOption); }); }); // 6. 窗口大小改变时重置图表大小 window.addEventListener(resize, function() { storeSalesChart.resize(); salesTrendChart.resize(); categorySalesChart.resize(); topDaysChart.resize(); }); });7. 运行与效果验证所有代码准备就绪现在让我们启动项目看看成果。7.1 启动Flask应用在项目根目录下确保虚拟环境已激活运行python app.py你应该能看到类似以下的输出* Serving Flask app app * Debug mode: on WARNING: This is a development server. Do not use it in a production deployment. * Running on http://127.0.0.1:5000 Press CTRLC to quit * Restarting with stat 数据库为空正在插入模拟数据... 模拟数据插入完成共1800条记录。 * Debugger is active!7.2 访问可视化平台打开浏览器访问http://127.0.0.1:5000。如果一切顺利你将看到一个包含四个卡片的仪表盘左侧上方各门店总销售额横向柱状图直观展示哪家店最赚钱。右侧上方销售趋势折线图默认显示全部门店总和。你可以使用下拉框选择特定门店图表会动态更新。左侧下方产品品类销售额占比饼图清晰展示哪种茶饮最受欢迎。右侧下方单日销量TOP10排行榜柱状图找出销量最高的那些“爆单日”。所有图表都是交互式的鼠标悬停可以查看精确数值。页面布局是响应式的在手机或平板电脑上也能良好显示。7.3 验证数据动态性为了验证数据是动态从数据库获取的你可以手动修改数据库需要一点SQL知识然后刷新页面查看图表变化。使用任何SQLite工具如DB Browser for SQLite打开项目根目录下的database.db文件。执行一条更新语句例如将“北京国贸店”的某条记录销售额改成一个很大的数字UPDATE sales_records SET sales 99999 WHERE store 北京国贸店 LIMIT 1;保存更改然后刷新浏览器中的仪表盘页面。你会发现“各门店总销售额”图表中“北京国贸店”的柱子明显变长。这证明了我们的系统不是静态的图片展示而是一个真正的、数据驱动的动态可视化平台。8. 常见问题与排查思路在实践过程中你可能会遇到以下问题。这里提供快速的排查指南。问题现象可能原因排查方式解决方案运行python app.py报ModuleNotFoundError依赖未安装或虚拟环境未激活1. 确认命令行前有(venv)。2. 运行pip list查看是否安装了flask, pandas。激活虚拟环境并执行pip install flask pandas numpy访问http://127.0.0.1:5000显示 “Not Found” 或空白页路由错误或静态文件路径问题1. 检查app.py中app.route(/)是否存在。2. 检查index.html是否在templates文件夹内。3. 查看浏览器控制台(F12)有无404错误如JS/CSS加载失败。确保文件结构正确Flask默认从templates和static文件夹读取。页面能打开但图表不显示控制台报JS错误JavaScript代码错误或API请求失败1. 按F12打开开发者工具查看“Console”面板报错信息。2. 查看“Network”面板API请求如/api/total_sales_by_store是否返回200状态码和数据。根据控制台错误修改main.js逻辑或检查Flask后端API是否能正常访问并返回JSON。图表显示“Loading”或数据为空数据库未初始化或API返回空数据1. 检查运行Flask时的控制台是否打印了“数据库为空正在插入模拟数据...”。2. 直接访问API地址如/api/total_sales_by_store看返回内容。确保init_database()函数被调用。可以尝试删除database.db文件重启Flask应用重新生成。修改了Python代码页面没变化浏览器缓存或Flask未自动重载1. 硬刷新浏览器CtrlF5。2. 确认app.run(debugTrue)已设置。使用debugTrue模式Flask会在代码改动后自动重启。如果不行手动停止并重启Flask服务。下拉框选择门店后趋势图没反应JavaScript事件未绑定或API参数错误1. 检查storeSelect的change事件监听器是否绑定成功。2. 在Network面板查看选择门店后发起的请求URL和响应。确保main.js中事件监听部分的代码正确且请求的URL格式为/api/daily_sales_trend?store门店名。9. 最佳实践与项目扩展建议这个项目是一个完美的起点。要把它变成一个更健壮、更实用的项目你可以从以下几个方向进行扩展9.1 代码结构优化使用蓝图(Blueprint)当路由越来越多时使用Flask蓝图将不同功能模块如auth.py,api.py,views.py分开让app.py更简洁。配置管理将数据库路径、密钥等配置信息移出代码使用config.py或环境变量管理。错误处理在API接口中添加更完善的错误处理try...except并返回统一的错误JSON格式。9.2 功能增强数据导入导出增加文件上传功能如CSV允许用户导入真实数据。同时提供数据导出为Excel或PDF报告的功能。用户交互添加日期范围选择器让用户可以查看任意时间段的销售数据。更多图表引入ECharts的地图组件如需展示全国门店或桑基图分析用户购买路径。用户登录使用Flask-Login等扩展增加简单的用户认证区分管理员和普通查看者权限。9.3 数据与性能更换数据库当数据量增大时将SQLite迁移到MySQL或PostgreSQL。只需修改data_processor.py中的连接字符串和少量SQL语法。加入缓存对于不经常变化的聚合数据如总销售额可以使用Flask-Caching将结果缓存几分钟减轻数据库压力。定时任务使用APScheduler等库定时从外部系统如ERP同步最新销售数据到数据库。9.4 部署上线使用生产服务器开发完成后使用Gunicorn或uWSGI配合Nginx来部署Flask应用替代内置的开发服务器。容器化编写Dockerfile将整个应用容器化实现环境一致和快速部署。这个项目已经为你搭建了一个坚实且清晰的技术框架。它不仅仅是一个课程设计的作业更是一个可以不断迭代、添加真实业务逻辑的数据可视化中台原型。通过动手实现它你不仅学会了如何串联Python数据分析、Web后端和前端可视化更重要的是掌握了如何将一个想法快速转化为一个可运行、可演示、可扩展的软件产品的基本方法论。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →