python框架之Flask基础篇(二)-------- 数据库的操作

1.flask连接数据库的四步:

  1. 倒入第三方数据库扩展包:from flask_sqlalchemy import SQLAlchemy
  2. 配置config属性,连接数据库:

    app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:[email protected]/first_flask"
    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
  3. 创建数据库first_flask
  4. 创建操作数据库对象:db = SQLAlchemy(app)

下面直接上代码解释:

# -*- coding:utf-8 -*-
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
# url的格式为:数据库的协议://用户名:密码@ip地址:端口号(默认可以不写)/数据库名
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:[email protected]/first_flask"
# 动态追踪数据库的修改. 性能不好. 且未来版本中会移除. 目前只是为了解决控制台的提示才写的
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 创建数据库的操作对象
db = SQLAlchemy(app)

class Role(db.Model):

    __tablename__ = "roles"
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(16),unique=True)
    # 给Role类创建一个uses属性,关联users表。
    # backref是反向的给User类创建一个role属性,关联roles表。这是flask特殊的属性。
    users = db.relationship(‘User‘,backref="role")
    # 相当于__str__方法。
    def __repr__(self):
        return "Role: %s %s" % (self.id,self.name)

class User(db.Model):
    # 给表重新定义一个名称,默认名称是类名的小写,比如该类默认的表名是user。
    __tablename__ = "users"
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(16),unique=True)
    email = db.Column(db.String(32),unique=True)
    password = db.Column(db.String(16))
    # 创建一个外键,和django不一样。flask需要指定具体的字段创建外键,不能根据类名创建外键
    role_id = db.Column(db.Integer,db.ForeignKey("roles.id"))

    def __repr__(self):
        return "User: %s %s %s %s" % (self.id,self.name,self.password,self.role_id)

@app.route(‘/‘)
def hello_world():
    return ‘Hello World!‘

if __name__ == ‘__main__‘:
    # 删除所有的表
    db.drop_all()
    # 创建表
    db.create_all()

    ro1 = Role(name = "admin")
    # 先将ro1对象添加到会话中,可以回滚。
    db.session.add(ro1)

    ro2 = Role()
    ro2.name = ‘user‘
    db.session.add(ro2)
    # 最后插入完数据一定要提交
    db.session.commit()

    us1 = User(name=‘wang‘, email=‘[email protected]‘, password=‘123456‘, role_id=ro1.id)
    us2 = User(name=‘zhang‘, email=‘[email protected]‘, password=‘201512‘, role_id=ro2.id)
    us3 = User(name=‘chen‘, email=‘[email protected]‘, password=‘987654‘, role_id=ro2.id)
    us4 = User(name=‘zhou‘, email=‘[email protected]‘, password=‘456789‘, role_id=ro1.id)
    us5 = User(name=‘tang‘, email=‘[email protected]‘, password=‘158104‘, role_id=ro2.id)
    us6 = User(name=‘wu‘, email=‘[email protected]‘, password=‘5623514‘, role_id=ro2.id)
    us7 = User(name=‘qian‘, email=‘[email protected]‘, password=‘1543567‘, role_id=ro1.id)
    us8 = User(name=‘liu‘, email=‘[email protected]‘, password=‘867322‘, role_id=ro1.id)
    us9 = User(name=‘li‘, email=‘[email protected]‘, password=‘4526342‘, role_id=ro2.id)
    us10 = User(name=‘sun‘, email=‘[email protected]‘, password=‘235523‘, role_id=ro2.id)
    db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])
    db.session.commit()
    app.run(debug=True)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

下面插播一条bug:

当把表格创建完成,注释这两句话:

 # 删除所有的表
    db.drop_all()
    # 创建表
    db.create_all()

然后向表格里面插入数据,此时会出现这样的错误:

sqlalchemy.exc.IntegrityError: (_mysql_exceptions.IntegrityError) (1062, "Duplicate entry ‘admin‘ for key ‘name‘") [SQL: u‘INSERT INTO roles (name) VALUES (%s)‘] [parameters: (‘admin‘,)]

查了网上的好多资料说把字段的约束unique=True去掉就好了,但是根本原因不在这。

原因就是因为app.run(debug=True)。开启debug模式之后,当我们修改代码的时候,比如将删除表和创建表这两句话注释,然后打开插入数据的注释。这个过程debug模式默认就已经把程序运行一遍了。此时数据库就已经有了数据,当我们再次手动执行的时候,又往数据库中插入了一条数据,这时候就会报错。因为字段的约束是唯一性的unique,所以解决的办法有两种:

第一种:就是不要将删除表和创建表这两句话注释,每次执行都要带着这两个句话。无论是debug模式自动执行还是我们手动执行程序,都会先删除表然后再创建表,所以执行多少次都不怕。

第二种:关闭debug模式。就是这样app.run()

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.数据库的增删改查:

1.以下的方法都是返回一个新的查询,需要配合执行器使用。

filter(): 过滤,功能比较强大。
filter_by():过滤,用在一些比较简单的过滤场景。

order_by():排序。默认是升序,降序需要导包:from sqlalchemy import * 。然后引入desc方法。比如order_by(desc("email")).按照邮箱字母的降序排序。

group_by():分组。

2.以下都是一些常用的执行器:配合上面的过滤器使用。

get():获得id等于几的函数。比如:查询id=1的对象。get(1)。切记:括号里没有“id=”,直接传入id的数值就ok。因为该函数的功能就是查询主键等于几的对象。

all():查询所有的数据。

first():查询第一个数据。

count():返回查询结果的数量。

paginate():分页查询,返回一个分页对象。paginate(参数1,参数2,参数3)

参数1:当前是第几页,参数2:每页显示几条记录,参数3:是否要返回错误。

返回的分页对象有三个属性:items:获得查询的结果,pages:获得一共有多少页,page:获得当前页。

3.常用的逻辑符:

需要倒入包才能用的有:from sqlalchemy import *

not_  and_  or_   还有上面说的排序desc。

常用的内置的有:in_      表示某个字段在什么范围之中。

4.其他关系的一些数据库查询:

endswith():以什么结尾。

startswith():以什么开头。

contains():包含

5.下面体会一下上面的这些用法:

1. 查询所有用户数据
User.query.all()
2. 查询有多少个用户
User.query.count()
3. 查询第1个用户
User.query.first()

4. 查询id为4的用户[3种方式]
User.query.get(4)
User.query.filter_by(id=4).first()    
User.query.filter(User.id==4).first()

filter:(类名.属性名==)
filter_by:(属性名=)

filter_by: 用于查询简单的列名,不支持比较运算符
filter比filter_by的功能更强大,支持比较运算符,支持or_、in_等语法。

5. 查询名字结尾字符为g的所有数据[开始/包含]
User.query.filter(User.name.endswith(‘g‘)).all()
User.query.filter(User.name.contains(‘g‘)).all()

6. 查询名字不等于wang的所有数据[2种方式]
 from sqlalchemy import not_注意了啊:逻辑查询的格式:逻辑符_(类属性其他的一些判断)
User.query.filter(not_(User.name==‘wang‘)).all()

User.query.filter(User.name!=‘wang‘).all()

7. 查询名字和邮箱都以 li 开头的所有数据[2种方式]
from sqlalchemy import and_
User.query.filter(and_(User.name.startswith(‘li‘), User.email.startswith(‘li‘))).all()

User.query.filter(User.name.startswith(‘li‘), User.email.startswith(‘li‘)).all()

8. 查询password是 `123456` 或者 `email` 以 `itheima.com` 结尾的所有数据
from sqlalchemy import or_
User.query.filter(or_(User.password==‘123456‘, User.email.endswith(‘itheima.com‘))).all()

9. 查询id为 [1, 3, 5, 7, 9] 的用户列表
User.query.filter(User.id.in_([1, 3, 5, 7, 9])).all()

10. 查询name为liu的角色数据
关系引用
User.query.filter_by(name=‘liu‘).first().role.name

11. 查询所有用户数据,并以邮箱排序
排序
User.query.order_by(‘email‘).all()  默认升序
User.query.order_by(desc(‘email‘)).all() 降序
12. 查询第2页的数据, 每页只显示3条数据
help(User.query.paginate)
三个参数: 1. 当前要查询的页数 2. 每页的数量 3. 是否要返回错误

pages = User.query.paginate(2, 3, False)
pages.items # 获取查询的结果
pages.pages # 总页数
pages.page # 当前页数

原文地址:https://www.cnblogs.com/RomanticLife/p/8372624.html

时间: 2024-08-10 02:02:12

python框架之Flask基础篇(二)-------- 数据库的操作的相关文章

python框架之Flask基础篇(一)

一.第一个hello world程序 # coding=utf-8 from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run(debug=True) 1.app参数的设置: 以下几种方式全部拿debug模式举例: .方式一:将参数设置到app.config字典中: app.conf

python框架之Flask基础篇(四)-------- 其他操作

1.蓝图 要用蓝图管理项目,需要导入的包是:from flask import Buleprint 具体大致分为三步: 1.先在子模块中导入蓝图包,然后再创建蓝图对象. 2.然后将子模块中的视图函数存储在蓝图对象中. 3.最后在主模块的文件夹里注册蓝图. 下面分别展示以上三步在项目中的具体操作: 第一步: 第二步: 第三步: 在子模块中运用模版:需要两步. 第一: 先要在pycharm中设置一下: 第二: 然后需要在创建蓝图对象的时候需要手动加上下面这句话: 前面那句话的意思是给url加上一个前

Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库上下文

导航 目   录:Farseer.net轻量级ORM开源框架 目录 上一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:数据库配置文件 下一篇:Farseer.net轻量级ORM开源框架 V1.x 入门篇:表实体类映射 前言 上文讲述了数据库配置使用,搭建好数据库的链接方式了我们知道怎么做了. 事实上,至今我们仍然还没有讲到代码方面,花了前面这么多篇幅讲解,主要是想由浅入深,不然一上来给大家讲解这讲解那的,听的也一头雾水,反而得不到效果. 这篇比较重要,因为它是我们在使用Far

Python面试重点(基础篇)

Python面试重点(基础篇) 第一部分 必答题 简述列举了解的编程语言及语言间的区别? pythonjavacc++c#gophp----------------------------------------------------------------编程语言分为解释型和编译型: 解释型语言:   python 在编写代码的时候不需要编译,在执行的时候,想要用专用的解释器对代码进行编译,全部编译后,才能执行代码 编译型语言:   c c++   go 每写一行代码,解释器就会编译一行,然

JMS基础篇(二)

简介 异构集成是消息发挥作用的一个领域,大型公司内部可能会遇到很多的平台,Java,.net或者公司自己的平台等. 传送消息还应该支持异步机制,以提高系统整体的性能.异步传输一条消息意味着,发送者不必等到接收者接收或者处理消息,可以接着做后续的处理. 应用程序发送消息至另外一个应用程序,需要使用到消息中间件.消息中间件应提供容错,负载均衡,可伸缩的事务性等特性. JMS与JDBC类似,是一种与厂商无关的API.应用程序开发者可以使用同样的API来访问不同的系统. 可以认为JMS是一种标准,各消息

php基础篇-二维数组排序 array_multisort

原文:php基础篇-二维数组排序 array_multisort 对2维数组或者多维数组排序是常见的问题,在php中我们有个专门的多维数组排序函数,下面简单介绍下: array_multisort(array1,sorting order, sorting type,array2,array3..)是对多个数组或多维数组进行排序的函数. array1 必需.规定输入的数组. sorting order 可选.规定排列顺序.可能的值是 SORT_ASC 和 SORT_DESC. sorting t

智普教育Python视频教程之入门基础篇,python笔记

智普教育Python视频教程之入门基础篇,python笔记 print id()内存地址 type()变量类型 windows命令行下edit命令 python数据类型不需要指定类型 定义hostname="www.google.com" 结果运行后总是告诉我NameError: name 'socket' is not defined 哪位帮我分析一下,怎么改才对 没用过socket,不过你试着在第一行加入 import socket C:\>notepad somefile.

php基础篇-二维数组排序姐妹篇

前面介绍了php多维数组排序的一个函数array_multisort() ,想了解的人可以点击 二维数组排序 array_multisort 下面介绍下不适用array_multisort()进行多维数组的排序. 这里介绍下2个php排序函数,一个是asort,一个是arsort. asort(array,sorttype) 函数对数组进行排序并保持索引关系.主要用于对那些单元顺序很重要的结合数组进行排序. 可选的第二个参数包含了附加的排序标识. SORT_REGULAR - 默认.以它们原来的

【新手学Python】一、基础篇

由于以前处理数据用Matlab和C,最近要处理大量文本文件,用C写实在是太繁琐,鉴于Python的强大文本处理能力,以及其在Deep Learning上有着很大优势,本人打算从即日起学习Python,谨以此系列博客记录学习点滴.文中如有错误,还望大牛们指出! Section 1: 本文是第一篇,当然也是基础,有了编程基础的我们都知道,学习一门语言什么最重要?当然先搞清楚数据类型和数据结构,有了这些,你才能去谈面向对象,才能去设计程序. Python的数据类型比较简单:1.整数;2.长整数;3.浮