Flask网站sqlalchemy连接mariadb

本文介绍了在Python3.6环境中,如何创建虚拟环境并启用,然后在Flask应用中配置并测试SQLAlchemy连接到MariaDB数据库的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  •    安装python3.6之后建立虚拟环境并启用,退出虚拟环境使用deactivate命令
 1007  python3 -m venv venv  #建立虚拟环境
 1008  source venv/bin/activate #启用虚拟环境
 1009  pip install pyodbc #虚拟环境下安装python扩展包
 1010  pip install --upgrade pip
 1011  pip install pyodbc
 1012  pip install ibm_db
 1013  pip --version
 1014  pip install pymysql #安装mysql驱动
  • Flask 中连接mariadb
# coding:utf8

import os
from datetime import datetime

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql

app = Flask(__name__)
app.debug = True

app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://lubaohui:lubaohui@127.0.0.1:3306/cbdb"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True

db = SQLALchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    name = db.Column(db.String(100), unique = True)

测试数据库连接:

(venv) [leo@linux pytest]$ ipython3
\/usr/lib/python3.6/site-packages/IPython/core/interactiveshell.py:763: UserWarning: Attempting to work in a virtualenv. If you encounter problems, please install IPython inside the virtualenv.
  warn("Attempting to work in a virtualenv. If you encounter problems, please "
Python 3.6.5 (default, Mar 29 2018, 18:20:46) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from models_with_appv2 import db,User

In [2]: db.create_all()

In [3]: u = User(name="leo")

In [4]: db.session.add(u)

In [5]: db.session.commit()

 

<think>我们被要求使用Flask框架开发一个包含会员管理、订餐功能和打印功能的Web应用,并使用MariaDB作为数据库。以下是一个分步的解决方案:###1.环境搭建首先,我们需要安装必要的Python包:```bashpipinstall flaskflask-sqlalchemy flask-migrate flask-login flask-wtfmariadb```- `flask`: Flask框架核心-`flask-sqlalchemy`:提供ORM支持-`flask-migrate`:数据库迁移工具-`flask-login`:用户会话管理- `flask-wtf`:表单处理- `mariadb`:MariaDB数据库驱动###2.项目结构创建项目目录结构如下:``` myapp/ ├── app/│├──__init__.py│├── models.py│├──routes.py│├── templates/ │└──static/├──config.py├── manage.py└── requirements.txt``` ###3.配置数据库在`config.py`中配置MariaDB数据库连接:```pythonimportosclass Config:SECRET_KEY =os.environ.get('SECRET_KEY') or'your-secret-key'SQLALCHEMY_DATABASE_URI= 'mariadb+mariadbconnector://username:password@localhost/dbname'SQLALCHEMY_TRACK_MODIFICATIONS =False``` ###4.初始化应用在`app/__init__.py`中初始化应用:```pythonfromflask importFlaskfrom flask_sqlalchemyimport SQLAlchemyfromflask_migrateimport Migratefrom flask_login importLoginManagerfromconfig importConfigapp =Flask(__name__) app.config.from_object(Config)db =SQLAlchemy(app) migrate= Migrate(app, db) login= LoginManager(app) login.login_view= 'login'from appimport routes, models```###5.定义数据模型在`app/models.py`中定义会员、订单等模型: ```pythonfrom appimport db, loginfromwerkzeug.security importgenerate_password_hash,check_password_hashfrom flask_login importUserMixinclass User(UserMixin,db.Model):id =db.Column(db.Integer, primary_key=True)username =db.Column(db.String(64), index=True,unique=True)email =db.Column(db.String(120), index=True,unique=True)password_hash= db.Column(db.String(128))#会员相关字段,如会员等级、积分等is_member =db.Column(db.Boolean,default=False)member_since =db.Column(db.DateTime)def set_password(self, password):self.password_hash =generate_password_hash(password)def check_password(self, password):return check_password_hash(self.password_hash,password)@login.user_loaderdef load_user(id):return User.query.get(int(id)) classFoodItem(db.Model):id =db.Column(db.Integer, primary_key=True)name =db.Column(db.String(100), nullable=False)price= db.Column(db.Float, nullable=False)description= db.Column(db.Text)class Order(db.Model):id =db.Column(db.Integer, primary_key=True)user_id= db.Column(db.Integer,db.ForeignKey('user.id'))total= db.Column(db.Float)items =db.relationship('OrderItem', backref='order',lazy='dynamic')class OrderItem(db.Model):id= db.Column(db.Integer,primary_key=True)order_id =db.Column(db.Integer, db.ForeignKey('order.id'))food_id= db.Column(db.Integer,db.ForeignKey('food_item.id'))quantity =db.Column(db.Integer) ```###6.创建路由和视图在`app/routes.py`中实现会员管理、订餐等功能: ```pythonfrom flaskimport render_template,redirect, url_for,request, flashfromflask_loginimport login_user,logout_user, current_user,login_requiredfrom appimport app, dbfromapp.modelsimport User, FoodItem,Order,OrderItemfromapp.forms importLoginForm, RegistrationForm,OrderForm@app.route('/') defindex():returnrender_template('index.html')@app.route('/register', methods=['GET', 'POST'])def register():form =RegistrationForm()if form.validate_on_submit():user =User(username=form.username.data, email=form.email.data)user.set_password(form.password.data)db.session.add(user)db.session.commit()flash('注册成功!')return redirect(url_for('login'))return render_template('register.html', form=form) @app.route('/login',methods=['GET','POST']) deflogin():form= LoginForm()ifform.validate_on_submit():user= User.query.filter_by(username=form.username.data).first()if useris Noneor notuser.check_password(form.password.data):flash('用户名或密码错误')returnredirect(url_for('login'))login_user(user, remember=form.remember_me.data)returnredirect(url_for('index'))returnrender_template('login.html',form=form)@app.route('/logout') deflogout():logout_user()return redirect(url_for('index')) @app.route('/menu')defmenu():food_items =FoodItem.query.all()return render_template('menu.html', food_items=food_items) @app.route('/order',methods=['GET','POST']) @login_requireddef order():form =OrderForm()#这里需要动态填充食物选择,具体实现略if form.validate_on_submit():#创建订单order =Order(user_id=current_user.id)db.session.add(order)db.session.commit()#添加订单项forfood_id,quantity inform.items.data:order_item =OrderItem(order_id=order.id,food_id=food_id,quantity=quantity)db.session.add(order_item)db.session.commit()flash('订单提交成功!')return redirect(url_for('index'))return render_template('order.html', form=form) ```###7.打印功能打印功能可以通过生成PDF或直接调用打印机实现。这里我们使用`reportlab`生成PDF:```pythonfromreportlab.pdfgen importcanvasfrom ioimport BytesIO@app.route('/print_order/<int:order_id>')@login_requireddefprint_order(order_id):order =Order.query.get_or_404(order_id)buffer =BytesIO()p =canvas.Canvas(buffer)p.drawString(100,750,f"订单号: {order.id}")y =700for itemin order.items:p.drawString(100, y, f"{item.food.name}x {item.quantity}")y-=20p.showPage()p.save()buffer.seek(0)returnsend_file(buffer,as_attachment=True, download_name=f'order_{order_id}.pdf', mimetype='application/pdf') ```###8.数据库迁移初始化数据库迁移仓库并创建数据库: ```bashflaskdb initflask dbmigrate -m "Initial migration" flask dbupgrade``` ###9.运行应用创建`manage.py`:```pythonfromapp importappif __name__== '__main__':app.run(debug=True) ```运行应用: ```bashpython manage.py``` ###注意事项1.需要根据实际需求完善表单和模板。 2.打印功能可能需要根据实际打印机进行调整,例如使用操作系统打印服务。3.会员管理功能可以扩展,如会员积分、折扣等。§§相关问题§§1. Flask中如何实现用户认证和授权?2.如何优化Flask应用的数据库查询性能?3.在Flask中如何实现异步任务(如发送邮件)? 4.如何部署Flask应用到生产环境?5.如何实现Flask应用的打印功能(直接连接打印机)?</think>### Flask Web应用开发:会员管理、订餐功能与打印集成(MariaDB) 我将为您设计一个基于Flask的完整解决方案,包含会员管理、订餐功能和打印系统,使用MariaDB作为数据库。 #### 一、技术栈设计 - **核心框架**: Flask + Flask-SQLAlchemy (ORM) - **数据库**: MariaDB (兼容MySQL) - **用户认证**: Flask-Login - **表单处理**: Flask-WTF - **打印方案**: ReportLab (PDF生成) + 系统打印API - **前端**: Bootstrap + Jinja2模板 #### 二、数据库设计(MariaDB) ```sql -- 会员表 CREATE TABLE members ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password_hash VARCHAR(128) NOT NULL, email VARCHAR(100) UNIQUE NOT NULL, phone VARCHAR(20), membership_level ENUM('basic', 'premium', 'vip') DEFAULT 'basic', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 菜品表 CREATE TABLE food_items ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, description TEXT, price DECIMAL(8,2) NOT NULL, category VARCHAR(50) ); -- 订单表 CREATE TABLE orders ( id INT AUTO_INCREMENT PRIMARY KEY, member_id INT NOT NULL, order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, total_amount DECIMAL(10,2) NOT NULL, status ENUM('pending', 'confirmed', 'preparing', 'delivered') DEFAULT 'pending', FOREIGN KEY (member_id) REFERENCES members(id) ); -- 订单明细表 CREATE TABLE order_details ( id INT AUTO_INCREMENT PRIMARY KEY, order_id INT NOT NULL, food_id INT NOT NULL, quantity INT NOT NULL, subtotal DECIMAL(8,2) NOT NULL, FOREIGN KEY (order_id) REFERENCES orders(id), FOREIGN KEY (food_id) REFERENCES food_items(id) ); ``` #### 三、Flask应用结构 ``` /flask-restaurant-app ├── app/ │ ├── __init__.py │ ├── models.py # 数据模型 │ ├── routes.py # 路由和视图 │ ├── forms.py # WTForms表单 │ ├── templates/ # Jinja2模板 │ │ ├── base.html │ │ ├── member/ │ │ ├── order/ │ │ └── print/ │ ├── static/ │ └── utils.py # 打印工具 ├── config.py # 配置文件 ├── requirements.txt └── run.py ``` #### 四、核心功能实现 1. **会员管理模块** (`app/routes.py`) ```python from flask import Blueprint, render_template, redirect, url_for from flask_login import login_required, current_user from .models import db, Member from .forms import RegistrationForm, LoginForm, ProfileForm member_bp = Blueprint('member', __name__) @member_bp.route('/register', methods=['GET', 'POST']) def register(): form = RegistrationForm() if form.validate_on_submit(): member = Member( username=form.username.data, email=form.email.data, phone=form.phone.data ) member.set_password(form.password.data) db.session.add(member) db.session.commit() return redirect(url_for('member.login')) return render_template('member/register.html', form=form) @member_bp.route('/profile', methods=['GET', 'POST']) @login_required def profile(): form = ProfileForm(obj=current_user) if form.validate_on_submit(): current_user.phone = form.phone.data current_user.membership_level = form.membership_level.data db.session.commit() return redirect(url_for('index')) return render_template('member/profile.html', form=form) ``` 2. **订餐功能模块** (`app/routes.py`) ```python from .models import FoodItem, Order, OrderDetail from .forms import OrderForm order_bp = Blueprint('order', __name__) @order_bp.route('/menu') def menu(): food_items = FoodItem.query.all() return render_template('order/menu.html', food_items=food_items) @order_bp.route('/place_order', methods=['POST']) @login_required def place_order(): cart_items = request.json.get('cart') total = sum(item['price'] * item['quantity'] for item in cart_items) new_order = Order( member_id=current_user.id, total_amount=total ) db.session.add(new_order) db.session.flush() # 获取order_id for item in cart_items: order_detail = OrderDetail( order_id=new_order.id, food_id=item['id'], quantity=item['quantity'], subtotal=item['price'] * item['quantity'] ) db.session.add(order_detail) db.session.commit() return jsonify({'order_id': new_order.id}) ``` 3. **打印功能实现** (`app/utils.py`) ```python from reportlab.lib.pagesizes import A4 from reportlab.pdfgen import canvas from io import BytesIO def generate_order_pdf(order): buffer = BytesIO() p = canvas.Canvas(buffer, pagesize=A4) # 打印头部 p.setFont("Helvetica-Bold", 16) p.drawString(100, 800, "餐厅订单收据") p.line(100, 790, 500, 790) # 订单信息 p.setFont("Helvetica", 12) p.drawString(100, 760, f"订单号: {order.id}") p.drawString(100, 740, f"日期: {order.order_date.strftime('%Y-%m-%d %H:%M')}") p.drawString(100, 720, f"会员: {order.member.username}") # 订单明细 y = 680 p.drawString(100, y, "菜品") p.drawString(300, y, "数量") p.drawString(400, y, "小计") y -= 30 for detail in order.details: p.drawString(100, y, detail.food.name) p.drawString(300, y, str(detail.quantity)) p.drawString(400, y, f"¥{detail.subtotal:.2f}") y -= 20 # 总计 p.line(100, y-10, 500, y-10) p.drawString(350, y-30, f"总计: ¥{order.total_amount:.2f}") p.showPage() p.save() buffer.seek(0) return buffer # 在路由中调用 @order_bp.route('/print_order/<int:order_id>') def print_order(order_id): order = Order.query.get_or_404(order_id) pdf_buffer = generate_order_pdf(order) # 发送到打印机(系统级调用) # 实际部署时使用打印队列服务 return send_file( pdf_buffer, mimetype='application/pdf', as_attachment=True, download_name=f'order_{order_id}.pdf' ) ``` #### 五、数据库配置 (`config.py`) ```python import os class Config: SECRET_KEY = os.environ.get('SECRET_KEY') or 'your-secret-key' SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://user:password@localhost/restaurant_db' SQLALCHEMY_TRACK_MODIFICATIONS = False ``` #### 六、部署与优化建议 1. **MariaDB优化**: - 为常用查询字段创建索引(如 `members.username`, `orders.member_id`) - 使用连接池配置 `SQLALCHEMY_POOL_SIZE` 2. **打印系统扩展**: - 使用Celery异步任务处理打印队列 - 集成物理打印机API(如EPSON ePOS SDK) 3. **安全加固**: - 密码哈希使用 `bcrypt` - 实现CSRF保护 - 订单数据验证 4. **部署方案**: ```bash # 使用Gunicorn + Nginx部署 gunicorn -w 4 run:app ``` #### 七、相关技术文档参考 - Flask-SQLAlchemy MariaDB配置: [^1] - Flask-Login用户认证: [^2] - ReportLab PDF生成: [^5]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值