flask再学习-思考之怎么从数据库中查询数据在页面展示!
看别人视频觉得很简单,要自己做蒙蔽了!这样子。NO!
1. 流程:
首先要有和数据库连接的驱动!一般有PYMySQL mysqlclient 等
使用扩展Flask-SQLAlchemy 获得orm对象
重点在于ORM对象的使用:
官方文档:http://docs.jinkan.org/docs/flask/patterns/sqlalchemy.html
http://www.pythondoc.com/flask-sqlalchemy/queries.html
2:使用 flask-sqlacodegen 扩展 方便快速生成 ORM model
2.1 :pip install flask-sqlacodegen
2.2 使用方法
生成所有表的对象:
flask-sqlacodegen mysql://root:@127.0.0.1/food_db --outfile "common/models/model.py" --flask
生成某个表的对象:
flask-sqlacodegen mysql://root:@127.0.0.1/food_db --tables user --outfile "common/models/user.py" --flask
注意:在window下mysql的部分不要加 ‘ ’ ,在Mac环境下要加 ‘ ’
3: 修改自动生成的model中的db变量
from application import db
4:修改配置文件
SQLALCHEMY_DATABASE_URI = 'mysql://root:对应root的密码@127.0.0.1/food_db'
5:开始写代码了
【前言】
使用python处理mysql数据库相关的业务,一般都是使用库MySQLdb直接调用sql语句。感觉很low,换一个SQLAlchemy上手。不但是耍酷,之前些flask代码时就很惊讶基本看不到对数据库的操作,其使用的就是修改过的SQLAlchemy,好处是直接操作数据库表对象,即ORM对象关系映射管理,性能会慢些,但在1-2倍的时间,在可以接受的范围。
安装
pip install sqlalchemy
pip install --egg mysql-connector-python-rf
pip install sqlacodegen
生成models
方法一: 自己根据SQLAlchemy的docs写model,比如一对多,多对一等复杂的表模型。(SQLAlchemy的文档非常详细,就跟天书一样,真心懒得看。还是flask-sqlalchemy的文档简洁明了,可以参考的)
方法二: 使用sqlacodegen从数据库逆向出models.py
$ sqlacodegen --noviews --noconstraints --noindexes \
--outfile ./models.py mysql://username:password@localhost:3399/dbname
这里需要注意下,使用–noviews, –noconstraints, –noindexes,这3个选项是去掉视图,约束和所以,基本用不到。反之,不去带着些文件结构的话可能会报错,比如views找不到数据。
数据库表-User
id | name | age |
---|---|---|
1 | ‘Tom’ | 22 |
2 | ‘Jim’ | 21 |
3 | ‘Lucy’ | 22 |
对应的models.py
# 导入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
# 创建对象的基类:
Base = declarative_base()
# 定义User对象:
class User(Base):
# 表的名字:
__tablename__ = 'user'
# 表的结构:
id = Column(String(20), primary_key=True)
name = Column(String(20))
基本使用
首先要创建engine,它代表一种数据库连接资源。可以通过engine船舰connect和session完成事务的提交。对于使用os.fork或者multiprocessing的多进程应用来说,通常需要为紫禁城提供单独的engine。
mysql:
engine = create_engine('mysql://scott:tiger@localhost/test')
#比较好的习惯是现实销毁引擎,会有助于python的垃圾回收
engine.dispose()
sqlite:
engine = create_engine('sqlite:///file.db')
查询记录
那么我们怎么从数据库中查询数据?为此,SQLAlchemy 在您的 Model 类上提供了 query 属性。当您访问它时,您会得到一个新的所有记录的查询对象。在使用 all() 或者 first() 发起查询之前可以使用方法 filter() 来过滤记录。如果您想要用主键查询的话,也可以使用 get()。
connect:
connection = engine.connect()
result = connection.execute("select username from users")
for row in result:
print("username:", row['username'])
connection.close()
Session:
# 创建DBSession类型:
DBSession = sessionmaker(bind=engine)
# 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
user = session.query(User).filter(User.id=='5').one()
# 打印类型和对象的name属性:
print 'type:', type(user)
print 'name:', user.name
# 关闭Session:
session.close()
使用更复杂的表达式查询一些用户:
>>> User.query.filter(User.email.endswith('@example.com')).all()
[<User u'admin'>, <User u'guest'>]
按某种规则对用户排序:
>>> User.query.order_by(User.username)
[<User u'admin'>, <User u'guest'>, <User u'peter'>]
限制返回用户的数量:
>>> User.query.limit(1).all()
[<User u'admin'>]
用主键查询用户:
>>> User.query.get(1)
<User u'admin'>
打印查询结果的全部元素:
for u in session.query(User).all():
print u.__dict__
插入记录
插入记录ret = session.add()
,其中ret的值永远是none,不用看。
Session:
try:
sess = Session()
sess.add(User())
sess.commit()
except gevent.Timeout:
sess.invalidate()
raise
except:
sess.rollback()
raise
删除记录
删除记录是十分类似的,使用 delete() 代替 add():
>>> db.session.delete(me)
>>> db.session.commit()
更改记录
基本思路是先filter到需要的行集合,再修改里面的值。这里有4种方式:
1) user.no_of_logins += 1
session.commit()
2) session.query().\
filter(User.username == form.username.data).\
update({"no_of_logins": (User.no_of_logins +1)})
session.commit()
3) conn = engine.connect()
stmt = User.update().\
values(User.no_of_logins = (User.no_of_logins + 1)).\
where(User.username == form.username.data)
conn.execute(stmt)
4) setattr(user, 'no_of_logins', user.no_of_logins+1)
session.commit()
事务
事物就是有一系列动作一气呵成,如果中间失败了,前面的动作不会生效。满足ACID特性。
最简单的例子就是转账,我给你转10块钱后台需要做两件事,先在我账户中减去10,再在你的账户里加10。想想如果这件事不用事务处理,我卡里减了10块钱,而转你钱没有成功,这十块钱就莫名消失了哈。
connection = engine.connect()
trans = connection.begin()
try:
r1 = connection.execute(table1.select())
connection.execute(table1.insert(), col1=7, col2='this is some data')
trans.commit()
except:
#一旦出错就回滚
trans.rollback()
raise
connection.close()
参考文献
stackoverflow.com: Convert sqlalchemy row object to python dict
flask再学习-思考之怎么从数据库中查询数据在页面展示!的更多相关文章
- MongoDB数据库中查询数据(下)
MongoDB数据库中查询数据(下) 在find中,options参数值为一个对象,用来设置查询数据时使用的选项,下面我们来对该参数值对象中可以使用的属性进行介绍: 1. fields; 该属性值为一 ...
- 在MongoDB数据库中查询数据(上)
在MongoDB数据库中查询数据(上) 在MongoDB数据库中,可以使用Collection对象的find方法从一个集合中查询多个数据文档,find方法使用方法如下所示: collection.fi ...
- 使用JDBC从数据库中查询数据的方法
* ResultSet 结果集:封装了使用JDBC 进行查询的结果 * 1. 调用Statement 对象的 executeQuery(sql) 方法可以得到结果集 * 2. ResultSet 返回 ...
- JDBC方式从数据库中查询数据并显示
1.创建数据库表myuser DROP TABLE IF EXISTS `myuser`; CREATE TABLE `myuser` ( `) NOT NULL COMMENT '姓名', `id` ...
- C#Web从0到1—创建一个web并从VS集成的SQLlocalDB数据库中查询数据
软件说明: VS2017,腾讯云服务器10元1个月,系统Win2012 R2标准版 第一步:建立第一个网页 建立工程 建好后,可以打开View选项打开项目资源浏览器和工具箱,后文会多次用到这两个版面 ...
- 使用JDBC从数据库中查询数据
* ResultSet 结果集:封装了使用JDBC 进行查询的结果 * 1. 调用Statement 对象的 executeQuery(sql) 方法可以得到结果集 * 2. ResultSet 返回 ...
- SAP 从数据库中查询数据,带有where 条件。
数据库表 代码 *& Report ZSELECT_DATA_FROM_ZMAST_CUST *&------------------------------------------- ...
- C#-WinForm-ListView-表格式展示数据、如何将数据库中的数据展示到ListView中、如何对选中的项进行修改
在展示数据库中不知道数量的数据时怎么展示最好呢?--表格 ListView - 表格形式展示数据 ListView 常用属性 HeaderStyle - "详细信息"视图中列标头的 ...
- Oracle数据库中的数据出错的解决办法
http://www.jcwcn.com/article/database/oracle/ 今天上班犯了一个严重的错误:把我们系统所使用的Oracle数据库中的数据给改掉了!当发现自己改错时,顿时冒了 ...
随机推荐
- Omi框架学习之旅 - 插件机制之omi-finger 及原理说明
以前那篇我写的alloyfinger源码解读那篇帖子,就说过这是一个很好用的手势库,hammer能做的,他都能做到, 而且源码只有350来行代码,很容易看懂. 那么怎么把这么好的库作为omi库的一个插 ...
- 洛谷 P1546 最短网络 Agri-Net
题目链接 https://www.luogu.org/problemnew/show/P1546 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当 ...
- Android Studio 导入工程
最简单的方式 等待加载完就好了 第二种方式 在导入别人的android studio项目(假设为项目A)时,会遇到gradle不一致的情况,以下简短介绍解决方法: 1. 打开要导入的项目的目录,删除下 ...
- Apache与Nginx
Apache与Nginx的优缺点比较 --- 1.nginx相对于apache的优点: 轻量级,同样起web 服务,比apache占用更少的内存及资源 抗并发,nginx 处理请求是异步非阻塞的 ...
- C# LINQ 详解 From Where Select Group Into OrderBy Let Join
目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...
- eclipse取消自动输入提示
在设置Eclipse自动提示后,按a-z都会显示提示,但是我们需要键入Enter才会输入,而默认的所有都键入,非常弱智,可采用下面方法设置. 1,先找到相关的插件: window -> show ...
- Linux中执行脚本参数获取
Linux中变量$[#,@,0,1,2,*,$,?]含义 $# 是传给脚本的参数个数 $0 是脚本本身的名字 $1 是传递给该shell脚本的第一个参数 $2 是传递给该shell脚本的第二个参数 $ ...
- 基于DDD的.NET开发框架ABP实例,多租户 (Saas)应用程序,采用.NET MVC, Angularjs, EntityFramework-介绍
介绍 基于ABPZERO的多租户 (Saas)应用程序,采用ASP.NET MVC, Angularjs-介绍 ASP.NET Boilerplate作为应用程序框架. ASP.NET MVC和ASP ...
- Bash 笔记
获取当前工作目录 basepath=$(cd `dirname $0`; pwd) 源文 : https://sexywp.com/bash-how-to-get-the-basepath-of-cu ...
- Redis+TwemProxy(nutcracker)集群方案部署记录
Twemproxy 又称nutcracker ,是一个memcache.Redis协议的轻量级代理,一个用于sharding 的中间件.有了Twemproxy,客户端不直接访问Redis服务器,而是通 ...