python下SQLAlchemy的使用
SQLAlchemy是python中orm常用的框架。支持各种主流的数据库,如SQLite、MySQL、Postgres、Oracle、MS-SQL、SQLServer 和 Firebird。
在安装好SQLAlchemy之后导入相关的模块,如下是一些常用的模块,也可以根据项目的实际需要在添加。
from sqlalchemy import Column, String, create_engine #导入包
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
定义数据模型,通常创建SqlTable.py(文件名称自定义就好)
# coding: utf-8 from sqlalchemy import Column, Integer, String, Float, BigInteger, Unicode, Text from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import ForeignKey, Sequence from sqlalchemy.orm import relationship from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker Base = declarative_base() class UserInfo(Base):#所有类继承自Base __tablename__ = 'UserInfo'#表的名字
#表的字段定义
primaryId = Column(Integer,Sequence('user'),primary_key=True) username = Column(Unicode(50)) password = Column(Unicode(50)) #以下为非必须方法,允许通过字典,对数据模型进行实例化 def __init__(self, user_dict): for key in user_dict: setattr(self, key, user_dict[key]) def update(self, info_dict): for key in info_dict: setattr(self, key, info_dict[key])
定义数据模型,数据模型中可以定义Id自增序列,在引用模块时添加Sequence,并且指定序列名称,如果多个数据模型共用一个序列,会导致非连续自增。
创建文件SqlManager.py,作用类似于C#中常见的SqlHellper,将SQLAlchemy的常用功能进行封装。
# coding: utf-8 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker import SqlTable from SqlTable import Base import utils #自定义模块 from sqlalchemy import and_ from sqlalchemy import desc from sqlalchemy import func config = utils.load_config() #自定义加载配置文件方法 engine = None Session = None class GetSession(object): def __init__(self): self.session = Session() def __enter__(self): return self.session def __exit__(self, exception_type, exception_value, exc_traceback): if exception_type is not None: self.session.rollback() log.error("session error:{}".format(traceback.format_tb(exc_traceback))) self.session.close() class SqlManager(objecet): def __init__(self): self._rlock = threading.RLock() global Session global engine engine = create_engine( "mysql+pymysql://{user}:{pwd}@127.0.0.1:3306/{dbname}?charset=utf8".format(
user=config["db_user"], pwd=config["db_password"], dbname=config["dbname"])) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) #以下为非必须举例,根据项目需求写增删改查,也可以通过泛型的思想编写一些 def add_user(self,username,pwd): with self._rlock: with GetSession() as session: user= User( name=username,password=pwd) session.add(user) session.commit()
def add(self,tabname,dictlist):#注意:如果参数为字典列表,数据模型中要有相应的通过字典初始化的方法 with self._rlock: table = getattr(SqlTable,tabname) engine.execute(table.__table__.insert(),dictlist) def update(self,tabname,dict): with self._rlock: with GetSession as session: table = getattr(SqlTable,tabname) result=session.query(table),filter(table.id=dict["id"]) if len(result)==0: new_info=table(dict) session.add(new_info) else: update_info=result[0] update_info.update(dict)#数据模型中需要有update方法 session.commit()
初始化数据连接 ,数据连接的基本格式为:数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名
如果提示引擎创建出错,可以尝试去掉数据库驱动名称,试运行等系统提示需要哪个模块,下载安装即可。
数据连接可以根据采用的数据库类型去拼接,有些数据库的驱动需要另外安装。创建方法如下:
engine = create_engine('mysql+pymysql://root:password@localhost:3306/test?charset=utf8')
engine = create_engine('sqlite:///' + unicode(config["db_path"], "utf-8")) #sqlite数据库可以直接指向地址,相对路径或绝对路径。
初始化数据库连接且数据模型创建完之后,需要在数据库中创建对应的表(有些类型的数据库需要手动创建),这一步可以交给SQLAlchemy来,代码如下:Base.metadata.create_all(engine) 。这行代码如果放在定义数据模型的最下边,会在import时运行,不建议放在sqltable.py中。上边代码放在了SqlManager类初始化的时候执行,避免import时加载的不受控制,具体原因会在正文后详述。
创建数据库会话类,这个类的实例可以当成数据库连接,同时还记录了一些的查询的数据并且决定什么时候才会执行数据操作。
Session = sessionmaker(bind=engine) #创建数据库会话类
数据库会话类的使用:
# 创建session对象:
session = Session()
# 创建新User对象:
new_user = User(id='5', name='Bob')
# 添加到session:
session.add(new_user)
# 提交即保存到数据库:
session.commit()
# 关闭session:
session.close()
或者使用with增加代码的健壮性:
new_user = User(id='5', name='Bob')
with GetSession() as session:
session.add(new_user)
session.commit()
基本操作到此可以应付日常工作,其他的进阶技能可以参考:http://blog.csdn.net/zd0303/article/details/50261347
关于with的使用:GetSession(),如上方法使用中的session是一个类对象,而且类中必须实现__enter__() 和__exit__()方法。