Web前端之Flask框架--sqlachemy数据库操作实现

一、Python数据库连接方式

1、python的两种数据库连接方式:

  • Python 标准数据库接口,使用 SQL 语句正常操作数据库。
    e.g: MySQL 关系型数据库的 pymsql 模块

  • 用 ORM 来进行数据库连接, Python 中使用sqlalchemy , flask中典型的 flask_sqlalchemy ,以面向对象的方式进行数据库的连接与操作

2、ORM是什么?有什么优势?

ORM ,即 Object-Relational Mapping (对象关系映射),它的作用是在关系型数据库和业务实体对
象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的 SQL 语句打交道,只需简单的操作对象的属性和方法。
在这里插入图片描述
图片解析:
使用对象关系映射时,面对不同的数据库不需要使用特定的数据库语言,使用简单的面向对象语言,比如python,通过OR Mapper和SQL Alchemy引擎将面向对象语言转换为对应的数据库语言如SQL等,对数据库中的数据进行处理,并且返回给用户的只是成功失败等结果。

二、什么是Flask-SQLAlchemy?

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

三、如何配置数据库

1、安装第三方模块

pip install -i https://pypi.douban.com/simple flask-sqlachemy

2、数据库配置

官方配置文档地址

#获取当前文件的绝对路径
import os
basedir=os.path.abspath(os.path.dirname(__file__))

#用于连接数据的数据库
SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(basedir,'data.sqlite')
#print(SQLALCHEMY_DATABASE_URI)
#sqlite:///D:\python课外学习\Web前端\Flsak\mycode\day4_sqlachemy数据库操作实现\data.sqlite

#sqlalchemy是否追踪对象的修改并且发送信息
SQLALCHEMY_TRACK_MODIFICATIONS=False

#每次请求结束之后自动提交数据库的变动
SQLALCHEMY_COMMIT_ON_TEARDOWN=True

配置文件完成后,需要导入到主函数文件run.py中

app.config.from_pyfile('config.py')
#从配置文件中导入数据库的配置
  • 流行的数据库引擎采用的数据库 URL格式
    在这里插入图片描述
  • 连接mysql数据库报错信息
import pymysql
pymysql.install_as_MySQLdb()

四、定义模型

1、数据库模型

from run import db
#数据库连接:db.Model--一个数据库模型
"""
create table users(id int primary_key,name varchar(20) unique);
"""
class User(db.Model):
    __tablename__='users'
    id=db.Column(db.Integer,autoincrement=True,primary_key=True)
    name=db.Column(db.String(20),unique=True)

if __name__ == '__main__':
    #创建模型文件中定义的数据库表,一个类对应一个数据库表
    db.create_all()

    #添加用户信息到users表中
    user=User(name='anan2')
    #1.添加到会话中
    db.session.add(user)
    #2.提交到数据库中
    db.session.commit()


    #查询数据库操作:filter_by根据姓名筛选用户信息,.first()获取列表中的第一个对象
    user=User.query.filter_by(name='anan').first()
    print('查询用户的信息:',user.id,user.name)

    #删除用户信息:要删除谁
    db.session.delete(user)
    db.session.commit()

    #修改用户信息:类似于添加
    user=User.query.filter_by(name='anan').first()
    user.name='yuyu'
    db.session.add(user)
    db.session.commit()

2、模型列类型

类型名python类型说明
Integerint普通整数,一般是32位
SmallIntegerint取值范围小的整数,一般是16位
BigIntegerint或long不限制精度的整数
Floatfloat浮点数
Numericdecimal.Decimal定点数
Stringstr变长字符串
Textstr变长字符串,对较长或不限长度的字符串做了优化
Unicodeunicode变长Unicode字符串
UnicodeTextunicode变长Unicode字符串,对较长或不限长度的字符串做了优化
Booleanbool布尔值
Datedatetime.date日期
Timedatetime.time时间
DateTimedatetime.datetime日期和时间
Intervaldatetime.timedelta时间间隔
Enumstr一组字符串
PickleType任何python对象自动使用Pickle序列化
LargeBinarystr二进制文件

3、模型列属性

选项名说明
primary_key如果设为True,这列就是表的主键
unique如果设为True,这列不允许出现重复的值
index如果设为True,为这列创建索引,提升查询效率
nullable如果设为True,这列允许使用空值;如果设为False,这列不允许设置空值
default为这列定义默认值

4、数据查询

1)查询过滤器
过滤器说明
filter()把过滤器添加到原查询,返回新查询
filter_by()把等值过滤器添加到原查询,返回新查询
limit()使用指定值限制原查询返回的结果数量,返回新查询
offset()偏移原查询返回的结果,返回新查询
order_by()排序返回结果,返回新查询
groupby()原查询分组,返回新查询
2)查询执行函数
方法说明
all()以列表形式返回结果
first()返回第一个结果,如果没有返回None
first_or_404()返回第一个结果,如果没有抛出404异常
get()返回主键对应记录,没有则返回None
get_or_404()返回主键对应记录,如果没有抛出404异常
count()返回查询结果数量
paginate()返回paginate对象,此对象用于分页

五、数据库关系

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

1、一对一关系

一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号。

在这里插入图片描述

1)模型定义
i、定义公民
class People(db.Model):
    __tablename__ = 'peoples'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(20), nullable=False)
    age=db.Column(db.Integer,default=18)
    
    def __init__(self,name):
        self.name=name
    def __repr__(self):
        return '<People:%s>'%(self.name)
ii、定义身份证
class Card(db.Model):
    __tablename__ = 'cards'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    cardID = db.Column(db.String(30), nullable=False)
    is_valid=db.Column(db.Boolean,default=True)
    
    def __repr__(self):
        return '<Card:%s>'%(self.name)
iii、关联身份证和公民

在公民类中添加:

#将公民和身份证关联起来,uselist=False指的是一个对象不对应一个列表,因此此时是一对一关系
#backref='People'指,在Card类里面添加属性信息名称为people,可以根据身份证获取用户公民信息
card=db.relationship('Card',backref='people',uselist=False)

在身份证中添加:

#添加外键是为了在用id对应公民时,是一一对应的而不是随便对应。'peoples'指的是表的名称
people_id=db.Column(db.Integer,db.ForeignKey('peoples.id'))
2)基本操作
if __name__ == '__main__':
    db.create_all()
    #增加
    p1=People(name='张三')
    p2=People(name='李四')

    c1=Card(cardID='001')
    c2=Card(cardID='002')

    # p1.card=c1
    # p2.card=c2
    c1.people=p1
    c2.people=p2

    db.session.add_all([p1,p2,c1,c2])
    db.session.commit()

    #删除
    Card.query.get(1)
    db.session.delete(c1)
    db.session.commit()

2、一对多关系

一个学生只属于一个班,但是一个班级有多名学生。

在这里插入图片描述

  • 设计数据库表:只需在学生表中多添加一个班级号的ID;
  • 通过添加主外键约束,避免删除数据时造成数据混乱。
1)模型定义
i、定义学生
class Student(db.Model):
    __tablename__ = 'students'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(20), nullable=False)
ii、定义班级
class Grade(db.Model):
    __tablename__ = 'grades'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(20), nullable=False)
iii、建立关联

在学生中添加外键:

#外键关联
grade_id=db.Column(db.Integer,db.ForeignKey('grades.id'))

在班级中:

#关系,backref='grade'指Student类中添加属性grade,userlist=True指一对多关系,即一个对象对应一个列表
students=db.relationship('Student',backref='grade')
2)基本操作
if __name__ == '__main__':
    db.create_all()

    #增加
    s1=Student(name='张三')
    s2=Student(name='李四')
    s3=Student(name='王五')

    grade1=Grade(name='python开发')
    grade2=Grade(name='Linux运维')

    grade1.students=[s1,s2,s3]
    db.session.add_all([s1,s2,s3,grade1,grade2])
    db.session.commit()

    #删除
    grade1=Grade.query.get(1)
    db.session.delete(grade1)
    db.session.commit()

3、多对多关系

一个学生可以选择多门课,一门课也有多名学生。
在这里插入图片描述

  • 对于多对多表,通过关系表就建立起了两张表的联系。
  • 多对多表时建立主外键后,要先删除约束表
    内容再删除主表内容。
    在这里插入图片描述
1)模型定义
i、定义学生
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)
    #关联,secondary=tags指定关系表对象
    courses=db.relationship('Course',secondary=tags)

    def __repr__(self):
        return "<MathStudent: %s >" % (self.name)
ii、定义课程
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 "<Course: %s >" % (self.name)
iii、建立关联表
#多对多关系,第三方表
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')))
2)基本操作
if __name__ == '__main__':
    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)
    #
    # course1.students.append(s3)
    #
    # 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)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值