一. 介绍

SQLAlchemy是一个基于Python实现的ORM框架。该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQL,然后使用数据API执行SQL并获取执行结果。

1
pip3 install sqlalchemy

组成部分:

  • Engine,框架的引擎
  • Connection Pooling ,数据库连接池
  • Dialect,选择连接数据库的DB API种类
  • Schema/Types,架构和类型
  • SQL Exprression Language,SQL表达式语言

SQLAlchemy本身无法操作数据库,其必须以来pymsql等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:

  1. MySQL-Python
  2. mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
  3.  
  4. pymysql
  5. mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
  6.  
  7. MySQL-Connector
  8. mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
  9.  
  10. cx_Oracle
  11. oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
  12.  
  13. 更多:http://docs.sqlalchemy.org/en/latest/dialects/index.html

二. 使用

1. 执行原生SQL语句

  1. import time
  2. import threading
  3. import sqlalchemy
  4. from sqlalchemy import create_engine
  5. from sqlalchemy.engine.base import Engine
  6.  
  7. engine = create_engine(
  8. "mysql+pymysql://root:123@127.0.0.1:3306/t1?charset=utf8",
  9. max_overflow=0, # 超过连接池大小外最多创建的连接
  10. pool_size=5, # 连接池大小
  11. pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
  12. pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
  13. )
  14.  
  15. def task(arg):
  16. conn = engine.raw_connection()
  17. cursor = conn.cursor()
  18. cursor.execute(
  19. "select * from t1"
  20. )
  21. result = cursor.fetchall()
  22. cursor.close()
  23. conn.close()
  24.  
  25. for i in range(20):
  26. t = threading.Thread(target=task, args=(i,))
  27. t.start()
  1.  

注意: 查看连接 show status like 'Threads%';

2. ORM

a. 创建数据库表

  1.  创建单表
  1.  创建多个表并包含FkM2M关系

指定关联列:hobby = relationship("Hobby", backref='pers',foreign_keys="Person.hobby_id")

b. 操作数据库

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. from sqlalchemy.orm import sessionmaker
  4. from sqlalchemy import create_engine
  5. from models import Users
  6.  
  7. engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/s6", max_overflow=0, pool_size=5)
  8. Session = sessionmaker(bind=engine)
  9.  
  10. # 每次执行数据库操作时,都需要创建一个session
  11. session = Session()
  12.  
  13. # ############# 执行ORM操作 #############
  14. obj1 = Users(name="alex1")
  15. session.add(obj1)
  16.  
  17. # 提交事务
  18. session.commit()
  19. # 关闭session
  20. session.close()
  1.  多线程执行示例
  1.  基本增删改查示例
  1.  常用操作
  1.  原生SQL语句
  1.  基于relationship操作ForeignKey
  1.  基于relationship操作m2m
  1.  其他

基于scoped_session实现线程安全

普通模式下使用sqlalchemy对数据库进行操作

  1. import threading
  2. from sqlalchemy.orm import sessionmaker
  3. from sqlalchemy import create_engine
  4. from models import Users
  5.  
  6. # 与数据库进行连接,并创建连接池
  7. engine = create_engine(
  8. "mysql+pymysql://root@127.0.0.1:3306/flask?charset=utf8",
  9. max_overflow=0, # 超过连接池大小外最多创建的连接
  10. pool_size=10, # 连接池大小,一次性最多建立的连接数
  11. pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
  12. pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
  13. )
  14. # 生成会话类
  15. Session = sessionmaker(bind=engine)
  16.  
  17. def task(arg):
  18. # 每次执行数据库操作时都要创建一个会话
  19. session = Session()
  20. session.query(Users).all()
  21. session.close()
  22.  
  23. for i in range(20):
  24. t = threading.Thread(target=task, args=(i,))
  25. t.start()

对于上述方式,每个线程里执行数据库的操作都要创建一个新的session会话,以保证当前线程操作的只是自己的会话对象,防止其他会话对象对当前线程中数据库操作的影响。但是这样不足之处在于需要为每个线程都要手动的创建session会话,那有没有其他比较好的方法为我们自动创建会话而且还能保证线程之间数据的安全?答案肯定是有的。

基于scoped_session实现操作数据库的线程安全

  1. import threading
  2. from sqlalchemy.orm import sessionmaker,scoped_session
  3. from sqlalchemy import create_engine
  4. from models import Users
  5.  
  6. # 与数据库进行连接,并创建连接池
  7. engine = create_engine(
  8. "mysql+pymysql://root@127.0.0.1:3306/flask?charset=utf8",
  9. max_overflow=0, # 超过连接池大小外最多创建的连接
  10. pool_size=10, # 连接池大小,一次性最多建立的连接数
  11. pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
  12. pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
  13. )
  14. # 生成会话类
  15. Session = sessionmaker(bind=engine)
  16. # 使用scoped_session创建一个单例的session,不需要为每次操作数据库创建会话
  17. session = scoped_session(Session)
  18.  
  19. def task(arg):
  20. session.query(Users).all()
  21. session.close()
  22.  
  23. for i in range(20):
  24. t = threading.Thread(target=task, args=(i,))
  25. t.start()

使用scoped_session创建一个全局的会话对象,该对象使用threading.local会为每一个线程开辟一个内存空间,并实例化一个原来Session类对象,将该对象保存到所创建的线程中去,从而保证了线程之间的数据安全。源码:

  1. session = scoped_session(Session)
  1. class scoped_session(object):
  2.  
  3. def __init__(self, session_factory, scopefunc=None):
  4.  
  5. # session_factory == Session = sessionmaker(bind=engine),即创建的会话Session类
  6. self.session_factory = session_factory
  7.  
  8. if scopefunc:
  9. self.registry = ScopedRegistry(session_factory, scopefunc)
  10. else:
  11. # self.createfunc = createfunc
  12. # self.registry = threading.local(),每创建一个 scoped_session 类实例则创建一个线程
  13. # 创建的 ThreadLocalRegistry 类实例拥有以上两个属性
  14. self.registry = ThreadLocalRegistry(session_factory)
  1. class ThreadLocalRegistry(ScopedRegistry):
  2. """A :class:`.ScopedRegistry` that uses a ``threading.local()``
  3. variable for storage.
  4.  
  5. """
  6.  
  7. def __init__(self, createfunc):
  8. # createfunc == Session类
  9. self.createfunc = createfunc
  10. self.registry = threading.local()

flask_sqlalchemy

  1. from flask import Flask
  2. from flask_sqlalchemy import SQLAlchemy
  3. # SQLAlchemy 类实例对象的创建一定要在引用蓝图之前,因为db会在各个蓝图中调用进行数据库操作
  4. db = SQLAlchemy()
  5. from sansa.views.account import account
  6. from flask_script import Manager
  7. from flask_migrate import Migrate,MigrateCommand
  8.  
  9. def create_app():
  10. """
  11. 创建app
  12. :return:
  13. """
  14. app = Flask(__name__)
  15. app.config.from_object("settings.Development")
  16. # 初始化db,读取app中关于数据库连接的配置信息,一定要放在导入配置之后
  17. db.init_app(app)
  18. app.register_blueprint(account)
  19. # 创建项目管理器
  20. manager = Manager(app)
  21. # 创建数据库迁移管理实例
  22. migrate = Migrate(app,db)
  23. # 为管理器添加一个db的命令
  24. manager.add_command("db",MigrateCommand)
  25. return manager
  1. from sansa import db
  2.  
  3. # 在数据库创建表一张表
  4. class Users(db.Model):
  5. __tablename__ = 'users'
  6.  
  7. id = db.Column(db.Integer, primary_key=True)
  8. # name = db.Column(db.String(32), index=True, nullable=False)
  9.  
  10. # 在数据库创建表一张表
  11. class School(db.Model):
  12. __tablename__ = 'school'
  13.  
  14. id = db.Column(db.Integer, primary_key=True)
  15. name = db.Column(db.String(32), index=True, nullable=False)

点我下载项目目录结构

flask之flask_sqlalchemy的更多相关文章

  1. Flask框架—flask_sqlalchemy组件使用

    一.flask_sqlalchemy组件 我们之前学过SQLAlchemy,一个独立的数据库关系对象映射,其实在flask中也有官方认可的第三方SQLAlchemy组件,用于处理flask中对象关系映 ...

  2. flask使用flask_sqlalchemy连接数据库(python2.7)

    1.出现编码问题 解决方法: #连接数据库时出现编码问题,需要pip install mysql-connector-python,并且数据库配置修改为 import mysql.connector ...

  3. flask程序部署在openshift上的一些注意事项

    https://www.openshift.com/blogs/how-to-install-and-configure-a-python-flask-dev-environment-deploy-t ...

  4. [Python][flask][flask-wtf]关于flask-wtf中API使用实例教程

    简介:简单的集成flask,WTForms,包括跨站请求伪造(CSRF),文件上传和验证码. 一.安装(Install) 此文仍然是Windows操作系统下的教程,但是和linux操作系统下的运行环境 ...

  5. [python][flask][flask-SQLAlchemy]关于flask-SQLAlchemy的初级使用教程

    鉴于网上关于flask-SQLAlchemy的实例使用教程参差不齐,于此写下工作学习过程中的使用过程,以便分享交流. 对于python关于flask有一定了解的高端玩家来说,请转至flask官方开发文 ...

  6. flask框架+pygal+sqlit3搭建图形化业务数据分析平台

    一. 前言 先说下主要的框架和主要的图形库的特点:(个人见解) Django:python开发的一个重量级的web框架,集成了MVC和ORM等技术,设计之初是为了使开发复杂的.数据库驱动的网站变得简单 ...

  7. 从零开始用 Flask 搭建一个网站(一)

    前言 笔者之前未接触过 Python,只是略懂一点前端,所以说从零开始也相差无几吧.Flask 是一个轻量级的基于 Python 的框架,但是扩展性非常良好(Github 上 22000 多个 sta ...

  8. flask 扩展之 -- flask-sqlalchemy

    flask-sqlalchemy.md 一. 安装 $ pip install flask-sqlalchemy 二. 配置 配置选项列表 : 选项 说明 SQLALCHEMY_DATABASE_UR ...

  9. python web开发-flask中sqlalchemy的使用

    SqlAlchemy是一个python的ORM框架. 在flask中有一个flask-sqlalchemy的扩展,使用起来很方便. 1.       创建一个sqlalchemy的Model模块 创建 ...

随机推荐

  1. Linq和EF 做 单一条件查询 和 复合条件 查询 以及 多表 联合查询 示例

    单一条件查询: var table2Object = (from t1 in db.table1 join t2 in db.table2 on t1.id equals t2.id select t ...

  2. Java 检查异常(checked exception)和未检查异常(unchecked exception)区别理解

    所有异常类型都是 Throwable 类的子类,它包含Exception类和Error类,Exception又包括checked exception和unchecked exception. unch ...

  3. 向文件写入一个数据块---write

    函数原型:ssize_t write(int fd,const void *buf,size_t count); 参数说明:fd:文件描述符,buf:写入数据的缓冲区,count:写入数据的最大长度. ...

  4. 让IIS 7 如同IIS 8 第一次请求不变慢

    当我们把网站部署在IIS7或IIS6S的时候,每当IIS或是Application Pool重启后,第一次请求网站反应总是很慢,原因大家都知道(不知道可以参考这个动画说明ASP.NET网页第一个Req ...

  5. 2018.09.01 hdu4405 Aeroplane chess (期望dp)

    传送门 期望dp简单题啊. 不过感觉题意不太对. 手过了一遍样例发现如果有捷径必须走. 这样的话就简单了啊. 设f[i]" role="presentation" sty ...

  6. 【Unity】1.3 Unity3D游戏开发学习路线

    分类:Unity.C#.VS2015 创建日期:2016-03-23 一.基本思路 第1步--了解编辑器 首先了解unity3d的菜单,视图界面.这些是最基本的基础,可以像学word操作一样,大致能明 ...

  7. Tomcat & SVN

    1. Tomcat简介 tomcat是一个web服务器,类似nginx,apache的http nginx,http只能处理html等静态文件(jpg) 网页分为静态网页(以.html或者.htm结尾 ...

  8. IntelliJ IDEA 2017版 spring-boot 实现jpa基本部署,通过实体类自动建立数据库

    一.添加Spring Boot JPA-Hibernate步骤 1.在pom.xml添加mysql,spring-data-jpa依赖      2.在application.properties文件 ...

  9. BZOJ 1007 [HNOI2008]水平可见直线 (栈)

    1007: [HNOI2008]水平可见直线 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7940  Solved: 3030[Submit][Sta ...

  10. ArcGIS Desktop Python add-ins 共享和安装插件

    1)   共享和安装插件 共享Python插件的关键是.esriaddin文件;为了获取该插件功能,其他用户只要在本机执行安装操作或通过网络引用该插件就可以. ArcGIS插件安装工具 当用户双击一个 ...