#! /usr/bin/env python3

# -*- coding:utf-8 -*-

#use SQLAlchemy

#ORM:Object-Relational Mapping ,把关系数据库的结构映射到对象上,SQLAlchemy是Python中有名的ORM框架

#导入sqlalchemy

from sqlalchemy import Column,String,create_engine

from sqlalchemy.orm import sessionmaker

from sqlalchemy.ext.declarative import declarative_base

#创建对象的基类:

Base=declarative_base()  #这个语句创建了一个Base类,这个类的子类可以自动与一个表关联

#定义创建表的函数

def init_db():

Base.metadata.create_all(engine) #该语句会找到base的所有子类,并在数据库中创建这些表,drop_all则是删除这些表

#定义删除表的函数

def drop_db():

Base.metadata.drop_all(engine)

#定义User表对象:

class User2(Base):

#表名:

__tablename__='user2'

#表结构:

id=Column(String(20),primary_key=True)

name=Column(String(20))

#初始化数据库连接:

DB_CONNECT_STRING='mysql+pymysql://rduser:1qaz@WSX@172.18.28.110:3306/test?charset=utf8'

#'mysql+pymysql'指定了使用mysql-python来连接  数据库名test和连接时使用的字符集charset=utf8可以省略。

engine=create_engine(DB_CONNECT_STRING,echo=True)

#create_engine()会返回一个数据库引擎,echo参数为True时,会显示每条执行的sql语句,生产环境下可关闭。

#创建DBSession类型:

DBSession=sessionmaker(bind=engine)

#sessionmaker()会生成一个数据库会话类。这个类的实例可以当成一个数据库连接,它同时还记录了一些查询的数据,并决定什么时候执行sql语句。

session=DBSession()

#init_db()

#以上代码完成SQLAlchemy 的初始化和具体每个表的class定义。如果有多个表就继续定义其他class,例School:

'''

class School(Base):

__tablename__='school'

id=...

name=...

'''

#create_engine()用来初始化数据库连接。SQLAlchemy用一个字符串表示连接信息:

# ‘数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名’

#根据需要替换掉用户名、口令等信息即可

#由于有了ORM,我们向数据库表中添加一行记录,可以视为添加一个User对象:

#创建session对象:

session=DBSession()

#创建新User对象,添加新记录:

new_user=User2(id='1',name='Glace')

#添加到session:

session.add(new_user)  #写入数据

user=User2(id='3',name='Smith')

session.add(user)

#提交即保存到数据库:

session.commit()

#关闭session:

session.close()

#可见,关键是获取session,然后把对象添加到session,最后提交并关闭。DBSession对象可视为当前数据库连接。

#有了ORM,查询出来的可以不再是tuple,而是User对象,sqlalchemy提供的查询接口如下:

#创建Session:

session=DBSession()

#创建DBSession类型:Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:

print(session.query(User2).filter(User2.id=='5').one())

print(session.execute('select * from User2 where id=:id',{'id':7}).first())

#打印类型和对象的name属性:

print('type:',type(User2))

print('name:',User2.name)

#关闭Session:

session.close()

#type: <class 'sqlalchemy.ext.declarative.api.DeclarativeMeta'>

#name: User2.name

#可见,ORM就是把数据库表的行与相应的对象建立关联,互相转换。

#由于关系数据库的多个表还可以用外键实现一对多、多对多等关联,相应的,ORM矿建也可以提供两个对象之间的一对多、多对多等功能。

#例如,如果一个User拥有多个Book,就可以定义一对多的关系:

'''

class User(Base):

__tablename__ = 'user'

id = Column(String(20), primary_key=True)

name = Column(String(20))

# 一对多:

books = relationship('Book')

class Book(Base):

__tablename__ = 'book'

id = Column(String(20), primary_key=True)

name = Column(String(20))

# “多”的一方的book表是通过外键关联到user表的:

user_id = Column(String(20), ForeignKey('user.id'))

'''

#当我们查询一个User对象时,该对象的books属性将返回一个包含若干个Book对象的list

#ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换。

http://docs.sqlalchemy.org/en/devel/

sqlalchemy通过被用作ORM框架,也可以当作普通的数据库接口使用,内带数据库连接池

from sqlalchemy import create_engine

conf="dialect+driver://username:password@host:port/database"    dialect表示数据的名字,diver表式连接数据库使用的模块名

example="mysql+pymysql://user:mima@192.168.2.251:3306/mydatabase?charset=utf8"           mysql

engine = create_engine('postgresql+psycopg2://scott:tiger@localhost/mydatabase')                                                postgresql

engine = create_engine('oracle://scott:tiger@127.0.0.1:1521/sidname')                                                                     oracle

engine = create_engine('mssql+pymssql://scott:tiger@hostname:port/dbname')                                                        sql server

engine = create_engine('sqlite:///foo.db')                                                                                                                     sqlite

engine=create_engine(conf,echo=True)      #echo是sqlalchemy内部的日志输出开关,默认为false

engine是一个数据库连接管理器, 创建engine时,实际上就创建了一个连接池pool和会话语法dialect

http://docs.sqlalchemy.org/en/devel/core/engines.html,sqlalchemy自带了很多数据连接引擎,个别需要安装相应模块,详见Dialectshttp://docs.sqlalchemy.org/en/devel/dialects/index.html

通过create_engine被创建时并没有实际连接数据库(表现为惰性连接),只有当engine。execute()或engine。connect()被首次执行时,才会创建实际的数据库连接。

创建个性化连接

def connect():
    return psycopg.connect(user='scott',host='localhost')

db=create_engine('postgresql://',creator=connect)

conn=engine.connect()

results=conn.execute('select username from users')  #ins可以是通过sqlalchemy创建的orm对象,也可以是sql语句

for row in results:
    print(username',row['username'])

conn.close()

这个conn是一个connection实例,为实际DBAPI连接的代理对象

results是代理结果实例,同DBAPI的cursor相联系,拥有大多cursor的特性。

当代理结果中的所有返回的rows被取出后,cursor就自动关闭了,例对于一个update操作不会返回row,cursor就会立刻关闭。

直接使用conn.execute(),是自动提交commit模式.即隐式提交

显式创建事务

conn=engine.connect()

trains=conn.begin()

try:

  results=conn.execute()

  r1=conn.execute(table.insert(),col1=7,col2='this is some data')

trans.commit()

except:

trans.rollback()

 raise

也可写作

with engine.begin() as connection:

r1=conn.execute(table.insert(),col1=7,col2='this is some data')

 r2=conn.execute()

with connection.begin() as trans: r1 = connection.execute(table1.select()) connection.execute(table1.insert(), col1=7, col2='this is some data')

r1.fetchall() 调用完一次后,再次调用就会返回一个空列表

r1.fetchmany()

r1.fetchone()

r1.lastrowid

r1.rowcount执行update或delete时返回的受影响行数

r1.close()关闭cursor

conn.close()

Pooling连接池

https://docs.sqlalchemy.org/en/latest/core/pooling.html

连接池是一个用于维护数据库 的 长时间连接,高效复用,对并发连接数 进行管理的标准技术

可以在创建engine时就传入参数进行自定义

engine=create_engine('postgresql://me@localhost/mydb',pool_size=20,max_overflow=0)

当engine执行connect()或execute()时,就会向连接池获取一个连接,连接池的默认模式为QueuePool,根据需要创建连接的模式。

QueuePool的默认连接数是5,最大连接数是10. 应该保持一个数据库一个engine,而不是为每次连接创建一个engine

所有的sqlalchemy连接池都不会预先创建连接,直到第一次被使用。

使用不同的pool模式,通过poolclass:

from sqlalchemy.pool importQueuePool

engine=create_engine('sqlite://file.db',poolclass=QueuePool)

禁用连接池,使用NullPool

engine=create_engine('postgresql+pscopg2://scott:tiger@localhost/test',poolclass=NullPool)

所有的pool类接收一个creator参数,用于创建一个新连接。 create_engine()接收这个参数,用来连接数据库

import sqlalchemy.pool as pool

import psycopg2

def getconn():

c=psycopg2.connect(username='ed',host='127.0.0.1',dbname='test')

return c

engine=create_engine('postgresql+psycopg2://',creator=getconn)

单独使用pool

mypool=pool.QueuePool(getconn,max_overflow=10,pool_size=5)

cursor=conn.cursor()

cursor.execute('select foo')

conn.close()

调用完conn.close()这个连接就被关闭,返还回连接池

 连接池事件Pool Event 

连接池支持一个事件接口用于处理上一个连接,基于每一个新的连接

关闭连接的处理

连接池可以刷新所有的单个连接,和它的连接设置,将池中之前的连接设置为无效。

比较适合用于数据库重启后导致之前池中所有连接失效时连接池的连接回收。有两者方法来实现它:

悲观处理关闭(每有一个新的的连接就发出一个简单的连接测试比例select 1,一旦该次结果返回异常,就认为连接断开了,这个连接会立即被回收,该连接之前的所哟连接也会被标记为无效,都会在使用之前被回收)

engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True)

乐观处理的方式之一 设置连接池的回收时长e=create_engine("mysql://scott:tiger@localhost/test",pool_recycle=3600)这样会使所有超过3600秒的连接被设置为无效连接并被替换。标记为无效的操作只在检查的过程的发生,而不是在每一个已被检查过的连接。 pool_recycle是连接池自带的功能,依赖于一个engine是否在被使用。这个设置适用于MySQL,MySQL会在间隔一个固定时间后自动关闭连接

在多进程中使用连接池

http://docs.sqlalchemy.org/en/devel/core/pooling.html

通常不建议在子进程中单独创建engine.

既不是在子进程中创建新的engine,也不是使用一个已存在的engine,而是调用engine.dispose(),在子进程开始connection之前。该方法会移除连接池中所有已存在的连接,重新创建所有的连接。写作如下:

TCP connections are represented as file descriptors, which usually work across process boundaries, meaning this will cause concurrent access to the file descriptor on behalf of two or more entirely independent Python interpreter states.

这意味这当前的到这个文件的连接代表这两个或者更多的完全独立的python接口状态,(可能是说,这个数据库的连接也代表了其他进程里的连接)

方法之一就是在 子进程创建连接之前调用 engine.dispose() 方法,dispose()是用于清除其他子进程中的连接,使在该进程的连接不影响其他的进程中的连接

engine=create_engine('...')

def run_in_process():
    engine.dispose()

with eng.connect() as conn:

    conn.execute('...')

p=Process(tartget=run_in_process)

另一种方式是设置连接池的事件,让其他的连接在这个子进程里自动失效,这种方式可能更合适

from sqlalchemy import event

from sqlalchemy import exc

import os

eng=create_engine('..')

@event.listens_for(engine,"connect")

def connect(dbapi_connection,connection_record):

  connection_record.info['pid']=os.getpid()

@event.listens_for(engine,"checkout")

def checkout(dbapi_connection,connection_record,connection_proxy):

  pid=os.getpid()

  if connection_record.info['pid']!=pid:

    connection_record.connection=connection_proxy.connection=None

    raise exc.DisconnectionError(

       "Connection record belongs to pid %s,"

       "attempting to check out in pid %s"%(connection_record.info['pid'],pid))

将sqlalchemy内置log部分加入日志,echo=True只是用于控制台的输出。

import logging

logging.basicConfig()

logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

转载于:https://www.cnblogs.com/Ting-light/p/9548198.html

sqlalchemy 简介相关推荐

  1. SQLAlchemy简介与入门

    ORM与SQLAlchemy简介 ORM ORM:Object Relation Mapping,最初主要描述的是程序中的Object对象和关系型数据库中Rlation关系(表)之间的映射关系,目前来 ...

  2. python3 数据库操作 orm sqlalchemy 简介

    ORM 全称 Object Relational Mapping, 翻译过来叫对象关系映射.简单的说,ORM 将数据库中的表与面向对象语言中的类建立了一种对应关系.这样,我们要操作数据库,数据库中的表 ...

  3. ORM SQLAlchemy 简介

    对象关系映射(Object Relational Mapping,简称ORM 使用DB-API访问数据库,需要懂 SQL 语言,能够写 SQL 语句,如果不想懂 SQL,又想使用关系型数据库,可以使用 ...

  4. SQLALchemy之Python连接MySQL

    20220225 https://www.cnblogs.com/toheart/p/9802990.html pymssql连接sqlserver https://blog.csdn.net/qq_ ...

  5. python数据库操作之pymysql模块和sqlalchemy模块(项目必备)

    pymysql pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同. 1.下载安装 pip3 install pymysql 2.操作数据库 (1).执行sql #! ...

  6. SQLAlchemy 教程 —— 基础入门篇

    参照博客:https://blog.csdn.net/qq_43355223/article/details/83024430 filter operator : 检索返回的列表,以及列表的标量 : ...

  7. SQLAlchemy 简单笔记

    ORM 江湖##### 曾几何时,程序员因为惧怕SQL而在开发的时候小心翼翼的写着sql,心中总是少不了恐慌,万一不小心sql语句出错,搞坏了数据库怎么办?又或者为了获取一些数据,什么内外左右连接,函 ...

  8. sqlalchemy mysql教程_SQLAlchemy 教程 —— 基础入门篇

    SQLAlchemy 教程 -- 基础入门篇 一.课程简介 1.1 实验内容 本课程带领大家使用 SQLAlchemy 连接 MySQL 数据库,创建一个博客应用所需要的数据表,并介绍了使用 SQLA ...

  9. Python sqlalchemy 连接常用的数据库

    python连接sqlServer数据库,Oracle数据库,MongoDB数据库,mysql数据库 python sqlalchemy 简介 学习链接 sqlalchemy是什么? sqlalche ...

  10. SQLAlchemy的基础使用

    一.ORM 与 SQLAlchemy 简介 ORM 全称 Object Relational Mapping, 翻译过来叫对象关系映射.简单的说,ORM 将数据库中的表与面向对象语言中的类建立了一种对 ...

最新文章

  1. C++ 获取当前时间的年,月,日,以及时分秒
  2. 牛津教授揭秘AI革命及其前沿进展
  3. Spacebuilder在Mono上运行修改备忘
  4. 一汽大众将召回3.7万辆存自燃隐患车辆
  5. 【计算机网络】关于IP数据报 首部检验和的反码问题(二进制反码)
  6. 带有第三方工具的Spring Boot Initilizr
  7. 重新复习数据结构-------ArrayList
  8. 计算机公式sin,三角函数计算公式大全
  9. cad沿线插入块 lisp_AutoCAD导出块名和块插入点列表(AutoLISP源码)——好用的AutoCAD块统计工具...
  10. VS2015导出带文件的项目模板
  11. 易语言源码翻译c,易语言编写翻译小工具源码
  12. 【数据分析项目实战】篇1:游戏数据分析——新增、付费和用户行为评估
  13. PV操作(操作系统)
  14. 计算机链接投影仪后不显示桌面,win10系统连接投影后不显示桌面图标怎么办
  15. VUE 拦截浏览器后退弹窗,弹窗一闪立刻消失问题
  16. Runloop与UITableView简单结合
  17. 兑吧开发规范《源Java手册》
  18. IE6-IE11兼容性问题列表及解决办法总结
  19. 仿鱼爪新媒交易账号过户转让平台源码担保第三方账号交易系统公众号服务号抖音快手小红书
  20. 手机投屏不是全屏怎么办_手机、电脑投屏怎么全屏

热门文章

  1. 一天到晚都在转笔,不需要写代码、调试,用眼看就行了?
  2. eclipse中如何搜索带\的字串
  3. 电荷为什么不随运动而变化
  4. 《我的祖国》正确英译应该是《The Evercountry, Mine》
  5. python 写配置文件,python配置文件写入过程详解
  6. mysql 6.17,mysql小结篇2(17.6.27)
  7. android 关闭jack_安卓编译 Jack server 错误问题解决办法
  8. vscode c++ 开发环境搭建(离线、内网)
  9. VS C# 删除数组中的一个或多个元素
  10. php微信公众号项目域名,微信公众号里“JS接口域名”实现分享功能