Flask数据库连接

文章目录

    • Flask数据库连接
        • Python数据库连接方式
        • Flask-SQLAlchemy
        • 配置数据库
            • 安装第三方模块
            • 数据库配置
            • 流行的数据库引擎采用的数据库 URL格式
            • 连接 mysql 数据库报错解决
        • 定义模型
            • 模型列类型
            • 模型列属性
        • 数据查询
            • 查询过滤器
            • 查询执行函数
        • 分页实现
            • 分页对象拥有的属性
            • 分页对象拥有的方法
    • 数据库关系
        • 一对一关系
            • 模型定义
            • 基本操作
        • 一对多关系
            • 模型定义
            • 基本操作
        • 多对多关系
            • 模型定义
            • 基本操作

Flask数据库连接

Python数据库连接方式

python中的数据库连接有两种方式:

  • Python 标准数据库接口,使用 SQL 语句正常操作数据库,
    e.g: MySQL 关系型数据库的 pymsql 模块
  • 用 ORM 来进行数据库连接, Python 中使用 sqlalchemy , flask中典型的 flask_sqlalchemy ,
    以面向对象的方式进行数据库的连接与操作
  • ORM 是什么?有什么优势?
    ORM ,即 Object-Relational Mapping (对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的 SQL 语句打交道,只需简单的操作对象的属性和方法。

Flask-SQLAlchemy

Flask-SQLAlchemy 是一个 Flask 扩展,简化了在 Flask 程序中使用 SQLAlchemy 的操作。
SQLAlchemy 是一个很强大的关系型数据库框架,支持多种数据库后台。 SQLAlchemy 提
供了高层 ORM ,也提供了使用数据库原生 SQL 的低层功能。

配置数据库

安装第三方模块
pip install flask-sqlalchemy
数据库配置

在app.py文件中:

from flask_sqlalchemy import SQLAlchemy
# 获取当前绝对路径
basedir = os.path.abspath(os.path.dirname(__file__)) app = Flask(__name__)
# SQLALCHEMY_DATABASE_URI: 用于连接数据的数据库。 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
# sqlchemy将会追踪对象的修改并且发送信号 
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 
# 每次请求结束之后都会提交数据库的变动 
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
# 数据库与app项目关联, 返回SQLAlchemy实例对象,
# 后面可以使用对象调用数据 db = SQLAlchemy(app)
流行的数据库引擎采用的数据库 URL格式

Flask数据库连接_第1张图片

连接 mysql 数据库报错解决

报错为:ImportError: No module named ‘MySQLdb’”
MySQLdb只支持Python2,还不支持python3可以用PyMySQL代替。

安装方法:pip install PyMySQL
然后在需要的项目中,把 init.py中添加两行:

    import pymysql
    pymysql.install_as_MySQLdb()

就可以用 import MySQLdb了。其他的方法与MySQLdb一样。

定义模型

模型(Model)这个术语表示程序使用的持久化实体。

class Role(db.Model):
	# __tablename__类变量定义数据库中表的名称。不指定默认为模型名称。
	# Flask-SQLAlchemy需要给所有的模型定义主键列,通常命名为id。
	id = db.Column(db.Integer, primary_key=True)
	name = db.Column(db.String(64), unique=True)
	# repr()显示一个可读字符串,用于调试和测试 
	def __repr__(self): 
		return '' % self.name 
class User(db.Model):
	__tablename__ = 'users' 
	id = db.Column(db.Integer, primary_key=True)
	username = db.Column(db.String(64), unique=True, index=True) 
	def __repr__(self): 
		return '' % self.username
模型列类型

Flask数据库连接_第2张图片

模型列属性

Flask数据库连接_第3张图片

数据查询

查询过滤器

Flask数据库连接_第4张图片

查询执行函数

Flask数据库连接_第5张图片

分页实现

分页对象拥有的属性

Flask数据库连接_第6张图片

分页对象拥有的方法

Flask数据库连接_第7张图片

数据库关系

数据库实体间有三种对应关系:一对一,一对多,多对多。

一对一关系

一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号。
Flask数据库连接_第8张图片

模型定义
# one_to_one.py文件 
from app import db import pymysql 
pymysql.install_as_MySQLdb() 
class People(db.Model):
 	__tablename__ = 'peoples' 
 	id = db.Column(db.Integer, primary_key=True, autoincrement=True)
  	name = db.Column(db.String(20), nullable=False) 
  	
	""" 
	 关系使用 relationship() 函数表示;
	 'Card': People类对应的表与Card类对应的表关联;
	 backref='people': 反向引用, 在Card类中添加新属性people; 
	 uselist=False: 默认为True, 如果为False代表一对一关系;
	 lazy='select': 决定了 SQLAlchemy 什么时候从数据库中加载数据; 
	 还可以设 定:'joined', 'subquery' , 'dynamic' 可能报错: 
	 SAWarning: Multiple rows returned with uselist=False for lazily- loaded
	"""
	 
   	card = db.relationship('Card', backref='people', uselist=False)
   	
   	def __init__(self, name): 
   		self.name = name 
   		
   	def __repr__(self): 
   		return '' % (self.name) 
   		
class Card(db.Model):
	__tablename__ = 'cards' 
	id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
	cardID = db.Column(db.String(30), nullable=False) 
	# 外键必须用类 sqlalchemy.schema.ForeignKey 来单独声明; 
	people_id = db.Column(db.Integer, db.ForeignKey('peoples.id')) 
	
	def __repr__(self): 
		return "" % (self.cardID)
基本操作

if __name__ == '__main__':
	db.drop_all() 
	db.create_all() 
	
	# 增元素 
	p1 = People(name="西部开源")
	p2 = People(name="粉条")
	db.session.add_all([p1, p2])
	db.session.commit()
	card1 = Card(cardID='001', people_id=p1.id)
	card2 = Card(cardID='002', people_id=p2.id) 
	db.session.add_all([card1, card2]) 	
	db.session.commit()
	
	# 查找 
	card_people1 = Card.query.filter_by(cardID='001').first().people 
	people_card1 = People.query.filter_by(id=1).first().card 
	print(card_people1) print(people_card1) 
	
	# 删除
	print("删除前: ", Card.query.all(), People.query.all()) 
	card = Card.query.filter_by(cardID='001').first() 
	db.session.delete(card) 
	db.session.commit()
	print("删除后: ", Card.query.all(), People.query.all())

一对多关系

一个学生只属于一个班,但是一个班级有多名学生。Flask数据库连接_第9张图片
设计数据库表:只需在 学生表 中多添加一个班级号的ID;
通过添加主外键约束,避免删除数据时造成数据混乱

模型定义
from app import db import pymysql 
pymysql.install_as_MySQLdb()
# 一对多: 外键写在多的一端; Grade:Stdudents== 1:n 

class Student(db.Model): 
	__tablename__ = 'students' 
	id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
	name = db.Column(db.String(20), nullable=False) 
	
	# 外键 
	grade_id = db.Column(db.Integer, db.ForeignKey('grades.id')) 
	
	def __repr__(self): 
		return "" % (self.id, self.name, self.grade_id) 
		
class Grade(db.Model): 
	__tablename__ = 'grades' 
	id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
	name = db.Column(db.String(20), nullable=False) 
	
	# 反向引用, 让Student类中添加属性grade; 
	students = db.relationship('Student', backref='grade') 
	
	def __repr__(self): 
		return "" % (self.id, self.name, self.students)
基本操作
if __name__ == '__main__': 
	db.drop_all() 
	db.create_all() 
	
	# 增元素 
	s1 = Student(name="西部开源") 
	s2 = Student(name="粉条")
	db.session.add_all([s1, s2]) 
	db.session.commit() 
	
	grade1 =Grade(name='Python开发')
	grade1.students.append(s1)
	grade1.students.append(s2)
	db.session.add_all([grade1])
	db.session.commit()
	print("添加成功: ", Student.query.all(), Grade.query.all())
	
	# 查找 
	student_grade1 = Student.query.filter_by(name='粉条').first().grade 
	grade_students = Grade.query.filter_by(name="Python开发").first().students 
	print(student_grade1)
	print(grade_students)
	
	# 删除
	print("删除前: ", Student.query.all(), Grade.query.all())
	grade1 = Grade.query.filter_by(name='Python开发').first()
	db.session.delete(grade1) 
	db.session.commit() 
	print("删除后: ", Student.query.all(), Grade.query.all())

多对多关系

一个学生可以选择多门课,一门课也有多名学生。在这里插入图片描述
对于多对多表,通过关系表就建立起了两张表的联系!多对多表时建立主外键后,要先删除约束表
内容再删除主表内容。Flask数据库连接_第10张图片

模型定义
from app import db import pymysql 
pymysql.install_as_MySQLdb() 
# 第三方表 
tags=db.Table('tags', 
		db.Column('student_id',db.Integer,db.ForeignKey('math_students.id')), 
		db.Column('course_id',db.Integer,db.ForeignKey('courses.id'))
	) 
	
class MathStudent(db.Model): 
	__tablename__ = 'math_students' 
	id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
	name = db.Column(db.String(20), nullable=False) 
	courses = db.relationship('Course', secondary=tags) 
	
	def __repr__(self): 
		return "" % (self.name)
		
class Course(db.Model):
	__tablename__ = 'courses' 
	id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
	name = db.Column(db.String(20), nullable=False) 
	students = db.relationship('MathStudent', secondary=tags) 
	
	def __repr__(self): 
		return "" % (self.name)
基本操作
if __name__ == '__main__': 
	db.drop_all()
	db.create_all() 
	
	# 创建
	s1 = MathStudent(name="拉格朗日")
	s2 = MathStudent(name="麦克劳林") 
	s3 = MathStudent(name="罗尔") 
	
	course1 = Course(name="高等数学")
	course2 = Course(name="线性代数") 
	
	s1.courses.append(course1) 
	s1.courses.append(course2)
	s2.courses.append(course1)
	s3.courses.append(course2) 
	
	db.session.add_all([s1, s2, s3, course1, course2]) 
	db.session.commit() 
	
	# 删除
	courseObj = Course.query.filter_by(name="线性代数").first() 
	studentObj = MathStudent.query.filter_by(name="罗尔").first() 
	
	print("删除前选择线性代数的学生: ", courseObj.students)
	
	courseObj.students.remove(studentObj) 
	
	print("删除后择线性代数的学生: ", courseObj.students)

你可能感兴趣的:(python框架)