一:关系型数据库 mysql

  Flask-SQLAlchemy管理关系型数据库。

  mysql数据库引擎:url : mysql://username:passowrd@hostname/database

  安装相关依赖包:

    pip install flask-sqlalchemy

    pip install flask-mysqldb  如果使用mysql数据库需要安装这个依赖包

  数据库连接配置:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE"] = "mysql://root:mysql@127.0.0.1:3306/flaskmysqltest" # 配置数据库的链接
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True # 请求结束后自动提交数据库的变动
app.config['SQLALCHEMY_ECHO'] = True # 执行后显示原始sql语句 db = SQLAlchemy(app) @app.route("/user")
def user():
pass if __name__ == '__main__':
app.run()

二:数据库模型 orm

  object-relationship-map 对象关系映射,简答说:就是通过创建实例对象==相当于在数据库中映射了一张表。

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE"] = "mysql://root:mysql@127.0.0.1:3306/flaskmysqltest"
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_ECHO'] = True db = SQLAlchemy(app) @app.route("/user")
def user():
pass # 定义对象
class Role(db.Model):
# 类变量定义了数据库中的表名。如果没有指定,会已类的名称小写为表名,也就是role
__tablename__ = "roles"
id = db.Column(db.Integer,primary_key=True) # create table roles(id int(64) primary key, name varchar(64) unique);
name = db.Column(db.String(64),unique=True) # desc roles;
def __repr__(self):
return "<Role %s>" % 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 "<User %s>" % self.username if __name__ == '__main__':
app.run()

  外键和关联的创建

# 定义对象
class Role(db.Model):
# 类变量定义了数据库中的表名。如果没有指定,会已类的名称小写为表名,也就是role
__tablename__ = "roles"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64),unique=True)
us = db.relationship("User",backref="role") # us这个字段,关联了User类(要写类名):backref="role"表明User类中可以反向引用role对象。 def __repr__(self):
return "<Role %s>" % 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)
role_id = db.Column(db.Integer,db.ForeignKey("roles.id")) # role_id 是关联了roles表的id字段。 def __repr__(self):
return "<User %s>" % self.username # 一对多的关系:一个role可以对应多个user用户。

  插入数据:

  报错:'Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. '

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app) # 错误一:db在app.config之后设置,应该为之前设置。
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:mysql@127.0.0.1:3306/flaskmysqltest" # 错误二:SQLALCHEMY_DATABASE_URI不是URL
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False   #SQLALCHEMY_COMMIT_ON_TEARDOWN 键,将其设为True时,每次请求结束后都会自动提交数据库中的变动
app.config['SQLALCHEMY_ECHO'] = True
if __name__ == '__main__':
app.run(debug=True)
db.create_all() # 执行所有的类,进行建表。roles 和 user表创建成功。
r1 = Role(name="admin") # 给roles表中插入数据
db.session.add(r1)
db.session.commit()

  删除所有的表

app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True 将这个从False改为True,请求后数据库自动提交数据变动,要不然删除不成功

if __name__ == '__main__':
  app.run(debug=True)
  db.drop_all() # 删除所有的表
  db.session.commit()

再次创建所有表

if __name__ == '__main__':
app.run(debug=True)
db.create_all()
db.session.commit()

再次执行删除所有的表

if __name__ == '__main__':
app.run(debug=True)
db.drop_all()
db.session.commit() 但是结果:表依然没有删除掉

到底是什么原因呢? 解决办法:重新启动flask框架,后再次执行后,才能实现删除表。

注意:重新建表和插入数据,也得重启flask框架才能生效。

if __name__ == '__main__':
app.run(debug=True)
db.create_all()
r1 = Role("admin")
r2 = Role("no_admin")
db.session.add_all([r1, r2])
db.session.commit()
问题:只执行了创表语句,插入语句没有执行,什么原因?是不是因为要db.create_all()也要用db.session.commit()
if __name__ == '__main__':
app.run(debug=True)
db.create_all()
db.session.commit()
r1 = Role(name="admin")
r2 = Role(name="noadmin")
db.session.add_all(r1,r2)
db.session.commit()
更改后:依然只能执行建表语句,插入数据不成功,到底是什么原因呢?原因是列表 db.session.add_all([r1,r2])没有加列表。然后还是要重启,框架插入语句才能被查询到。

全部的问题:框架运行到app.run()就阻塞了,当关闭框架时,会执行到,后面的语句,语句才生效,我太笨了。

继续连续两次ctrl+s框架自动刷新,报错:

sqlalchemy.exc.IntegrityError: (pymysql.err.IntegrityError) (1062, "Duplicate entry 'aaaaaa' for key 'name'") [SQL: 'INSERT INTO title (name) VALUES (%(name)s)'] [parameters: {'name': 'aaaaaa'}]
原因是:username设置的 unique=True,再次插入遇到重复的名字就报错了。

三:sqlalchemy语句的操作

实例:通过python shell 的方式操作数据库

  终端中打开 ipython

  输入 from mysql_tesst impoty User,Role 报错:

  Non-ASCII character '\xe7' in file mysql_test.py on line 16, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details。

  原因是:ipython 版本默认使用的是 Python2.7.12 在python2的版本中,程序中有中文或者中文注释,第一行必须加上,# encoding: utf-8。

  pip3 install ipython 将ipython的版本换成python3的版本就行了

 下面将使用python shell的ipython3操作数据库

  1.表中插入数据

from mysql_test import User,db

r1 = Role(name="Admin2")  # 1.模型定义:

print(r1.id)  # None

db.session.add(r1) # 2.增加模型到数据库的操作层

db.session.commit() # 3.将模型转换为mysql的原生语句,进行插入数据。

print(r1.id) # 3  # 获取表中某个字段,直接通过实例属性r1.id进行取值,方便。  select id from roles where name="Admin2" 



# 为什么id不是按照顺序排列的,
# 原因是:id字段设置时候,只是设置了为primary key并没有设置为自增类型,auto_increment

  2. 修改表中的字段信息

还是在上次的shell基础上进行操作

要求:将表中的Admin2字典修改为admin2

r1.name = "admin2"  # 通过赋值的方式修改表中name的值

db.session.add(r1)  

db.session.commit()

print(r1.name)  # admin2

  3. 删除表的数据

# 接着上面的shell

db.session.delete(r1)

db.session.commit()

  4.查询数据:sqlalchemy提供了 query对象进行数据查询

Role.query.all()  # query.all()表示查询所有的数据

[<Role admin>, <Role noadmin>]  查询操作,没有修改表的结构,因此不需要session.commit():返回的是查询的对象

返回的样式为什么是这样呢?
def __repr__(self):
return "<Role %s>" % self.username 原因是:模型类中定义的这个函数进行决定的。

  查询数据query配合过滤器filter可以更加准确的查询所需要的数据

User.query.filter_by(username="张惠妹").all()  

[<User 张惠妹>]  # 显示的样式同上


  查询users中用户id大于2的所有用户

User.query.filter_by(id>1).all()  # 原因:filter_by只能用于等值过滤。
User.query.filter(id>1).all() # 原因:id 应该改为User.id 表示是这个表的id字段。 # 以上两种方式的查询均报错:
unorderable types: builtin_function_or_method() > int() 扩展:filter()中条件的写法

  users = User.query.filter(条件1).first()
  条件的写法:
  User.name.endswith('g')
  User.name.startswith('g')
  User.name.containswith('g')
  User.name == “laowang”
  User.age == 12
  User.age > 12
  User.id.in_(列表)

  查询users中的id大于2且名字为张学良的用户

User.query.filter(User.id>1 ,User.username=="张学良").all() 

[<User 张学良>]

扩展:filter()中多条件查询的写法

  users = User.query.filter(条件1,条件2,条件3).first()
  users = User.query.filter(or_(条件1,条件2,条件3)).first()
  users = User.query.filter(not_(条件1)).all()

  其他的过滤条件

排序
User.query.order_by(字段.哪一种排序).all()
User.query.order_by(User.name.desc()).all() 分页
aa = User.query.paginate(第几页,每一页几条)
aa.pages
aa.page
aa.items

  执行函数

3.视图中操作数据库

  # todo

  

flask之数据库的交互的更多相关文章

  1. Flask之数据库设置

    4 数据库 知识点 Flask-SQLALchemy安装 连接数据库 使用数据库 数据库迁移 邮件扩展 4.1 数据库的设置 Web应用中普遍使用的是关系模型的数据库,关系型数据库把所有的数据都存储在 ...

  2. SQL*Plus 与数据库的交互(SQL*Plus时什么)

    Oracle 的 SQL*Plus 是与数据库进行交互的客户端工具,在 SQL*Plus中,可以运行 SQL*Plus 命令与 SQL*Plus 语句.   SQL*Plus 时一个基于 C/S 两层 ...

  3. flask修改数据库字段的类型和长度

    flask修改数据库字段的类型和长度 ​ 在将models中的字段的db.String(256)修改为db.String(1024)后,执行migrate和upgrade操作后,发现数据库并没有更新, ...

  4. 数据库的交互模式 常用的dos命令 (第一天)

    浏览器和服务器和数据库的交互模式 windows nt(windows系统)的分类:服务操作系统有(server03 server08(R2) 12 16) 个人操作系统有(xp win7 win8 ...

  5. flask从数据库反向导入Model以及出现报错No module named sqlacodegen.main

    使用flask的朋友肯定了解了flask_sqlalchemy,不了解的小伙伴也可以查看博文:Flask 操作Mysql数据库 - flask-sqlalchemy扩展 上面博文中讲解了如何将flas ...

  6. 编写一个简单的flask的前后端交互的网页(flask简单知识的讲解)

    实验原理: 1.什么是flask Flask是一个使用Python编写的轻量级Web应用框架,其WSGI工具采用Werkzeng,模板引擎使用Jinja2.Flask与 Django之间的区别就是Dj ...

  7. 实验3、Flask数据库操作-如何使用Flask与数据库

    1. 实验内容 数据库的使用对于可交互的Web应用程序是极其重要的,本节我们主要学习如何与各种主要数据库进行连接和使用,以及ORM的使用 2. 实验要点 掌握Flask对于各种主要数据库的连接方法 掌 ...

  8. 利用ajax的方式来提交数据到后台数据库及交互功能

    怎么样用ajax来提交数据到后台数据库,并完成交互呢????? 一.当我们在验证表单的时候,为了阻止把错误的也发送到服务器,我们通常这样设置:     $(function(){       var ...

  9. C#_数据库基本交互

    //app.config <?xml version="1.0" encoding="utf-8" ?> <configuration> ...

随机推荐

  1. 003-CHROME开发者工具的小技巧

    首先调试先进入到调试模式,快键键F12 1.代码格式化 有很多css/js的代码都会被 minify 掉,你可以点击代码窗口左下角的那个 { }  标签,chrome会帮你给格式化掉. 2.强制DOM ...

  2. Delphi XE2 之 FireMonkey 入门(12) - 动画(上)

    在 HD 窗体上添加一个 TAniIndicator, 修改其 Enabled 属性为 True, 动画完成了. 这是最简单的动画相关的控件了, 只有两个值得注意的属性: Enabled: Boole ...

  3. js高级写法

    名称 一般写法 优化 取整(不四舍五入) parseInt(a,10); //Before Math.floor(a); //Before a>>0; //Before ~~a; //Af ...

  4. 类LinkedHashSet

    /* * LinkedHashSet底层数据结构由哈希表和链表组成 * 哈希表保证元素的唯一性 * 链表保证元素有序(存储和取出是一致的) * */ import java.util.LinkedHa ...

  5. 从DT时代云栖大会聊聊恒生电子

    从IT到DT,除了HOMS和配资,本文结合互联网金融的背景,帮助读者对恒生电子600570了解更多. 马云在2015杭州·云栖大会Computing Conference发表致辞时多次强调DT(Dat ...

  6. 错误:Only the original thread that created a view hierarchy can touch its views——Handler的使用

    在跟随教程学习到显示web页面的html源码时报错:Only the original thread that created a view hierarchy can touch its views ...

  7. 设置HTML中字体的粗细

    设置font-weight 属性:normal : 默认值.正常的字体.相当于 400 .声明此值将取消之前任何设置bold : 粗体.相当于 700 .也相当于 b 对象的作用bolder : 比 ...

  8. Navicat批量导出mysql的DDL语句

    工作中有的时候需要将某个库中的表.视图.函数.存储过程等创建语句导出,又不需要表中的数据.同时最好放在同一个文件里面,这样方便拷贝. 方法一:需要拷贝的创建语句条数不多,不至于让你拷到头脑发晕的地步, ...

  9. Java对象多态性——对象的转型(引用类型之间的类型转换)

    Java引用变量有两个类型:编译时类型和运行时类型.编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定. 若编译时类型和运行时类型不一致,就出现多态 正常的方法调用(本态调用 ...

  10. Visual Studio文件属性

    Visual Studio文件属性主要用到的为:复制到输出目录和生成操作. 复制到输出目录根据选项就可以明白是标示该文件是否输出到生成的目录地址: 生成操作则主要指该文件在执行生成时对文件执行的何种操 ...