Python与数据库[2] -> 关系对象映射/ORM[0] -> ORM 与 sqlalchemy 模块
ORM 与 sqlalchemy
1 关于ORM / About ORM
1.1 ORM定义 / Definition of ORM
ORM(Object Relational Mapping),即对象关系映射。简单的说,ORM将数据库中的表与面向对象语言中的类建立了一种对应关系。这样,我们要操作数据库,数据库中的表或者表中的一条记录就可以直接通过操作类或者类实例来完成。
如果写程序用适配器(Adaptor)和程序交互,则需要要写原生SQL语句。如果进行复杂的查询,那SQL语句就要进行一点一点拼接,而且不太有重用性,扩展不方便。而且写的SQL语句可能不高效,导致程序运行也变慢。ORM 相当于把数据库实例化了,在代码操作SQL数据库中又加了ORM这一层。
ORM的优点:
- 隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。
- ORM使我们构造固化数据结构变得简单易行。
ORM的缺点:
无可避免的,自动化意味着映射和关联管理,代价是牺牲性能(早期,这是所有不喜欢ORM人的共同点)。现在的各种ORM框架都在尝试使用各种方法来减轻这块(LazyLoad,Cache),效果还是很显著的。
1.2 Active Record模式 / Active Record Mode
Active Record模式属于软件设计模式的一种,它将对象的操作与数据库的动作对应起来,ORM对象本质是表中的数据行,也就是当操作ORM对象的属性时,会自动对数据库进行相应的操作。
目前sqlalchemy已将其自带的声明层修改为Active Record模式。
2 sqlalchemy库 / sqlalchemy library
SQLAlchemy 是Python 社区最知名的 ORM 工具之一,为高效和高性能的数据库访问设计,实现了完整的企业级持久模型。使用方式可以参考官方文档。
2.1 关于sqlalchemy / About sqlalchemy
2.1.1 版本区别 / Difference between Version
对于sqlalchemy来说,存在一个值得注意的问题,当sqlalchemy的版本大于1.0,且使用pyodbc适配器的时候,会对ODBC所使用的驱动参数要求进行指明。而在旧版本例如0.9.9中则无需指明会进行自动选择。
例如连接SQL Server,在0.9.9版本中,可以不指定驱动,
connection = 'mssql+pyodbc://username:password@host:port/database'
而在1.0以上的版本中则需要对驱动进行指定,
connection = 'mssql+pyodbc://username:password@host:port/database?Driver=SQL Server'
2.1.2 使用参考 / Usage Reference
使用的方式除了参考官方文档外,还有以下链接:
http://blog.csdn.net/fgf00/article/details/52949973
http://www.cnblogs.com/liu-yao/p/5342656.html
2.2 模块 / Module
sqlalchemy有许多模块,在sqlalchemy包的__init__中可以看到,初始化时对各个模块中比较常用的模块进行了导入,下面将分别对这些模块中较为重要的函数或类进行一定介绍,若无说明则以.module_name代指sqlalchemy.module_name。
由于sqlalchemy中的导入关系,具体实现方法所在位置参考源代码。
2.2.1 .engine模块
在.engine的__init__中,包含了对该模块内的各个py文件介绍,engine模块中的介绍如下,engine模块定义了一套使用高级结构语句,连接管理,执行及结果的组件,用于实现与DB-API模块接口。其中最主要的类在于Engine,主要构建函数为create_engine()。
2.2.1.1 create_engine()函数
函数调用: engine = create_engine(url, **kwargs)
函数功能:创建驱动实例
传入参数: url, kwargs
url: str类型,dialect[+driver]://user:password@host/dbname[?key=value..]形式存在
echo: bool类型,可以设置执行时是否显示原始SQL语句
返回参数: engine
engine: obj类型,返回的一个引擎实例
Note: ‘dialect’ is a database name such as ‘mysql’, ‘oracle’, ‘postgresql’, etc., ‘driver’ is the name of a DBAPI, such as ‘psycopg2’, ‘pyodbc’, ‘cx_oracle’, etc. Alternatively, the URL can be an instance of :class: ‘~sqlalchemy.engine.url.URL’.
2.2.2 .orm模块
2.2.2.1 relationship()函数
函数调用: t_rel = orm.relationship(argument, secondary=None, backref=None, **kargs)
函数功能:生成一个关系属性(relationship property)对象实例
传入参数: argument, secondary, backref,
argument: str类型,一个映射的类,或者实际的类,映射器实例,代表关系对象的目标
secondary: obj类型,在多对多的关系对象中,用于指明中间表,通常这是一个关系表的类实例
backref: str类型,用于指明当前关系属性需要放置映射器类的名称
返回参数:
t_rel: obj类型,关系对象实例
E.g.:
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship("Child", order_by="Child.id")
2.2.2.2 Session模块
2.2.2.2.1 sessionmaker类
类实例化: Session = orm.sessionmaker(bind=None, **kwargs)
类的功能:可配置的Session工厂函数,会创建一个新的Session类
传入参数: bind, kwargs
bind: obj类型,可传入一个连接对象(引擎),bind=engine
返回参数: Session
Session: class类型,返回的一个Session类,可以用于产生session实例
Note: 重新传入的参数会覆盖原本传入的参数
E.g.:
# global scope
Session = sessionmaker(autoflush=False)
# later, in a local scope, create and use a session:
sess = Session()
# Any keyword arguments sent to the constructor itself will override the
# "configured" keywords::
Session = sessionmaker()
# bind an individual session to a connection
sess = Session(bind=connection)
2.2.2.2.2 Session类
类实例化: ses = Session()
类的功能:生成一个会话实例
传入参数: kwargs
返回参数: ses
ses: obj类型,返回的一个Session类实例
Note: 此处的参数可由sessionmaker传入,也可在实例化使自主重定义
2.2.2.2.2.1 execute()方法
函数调用: re = ses.execute(clause, params=None, mapper=None, bind=None)
函数功能:利用会话对象执行SQL语句或一个表达式结构
传入参数: clause, params, mapper, bind
clause: str/obj类型,可以传入原生SQL语句字符串(与适配器相同),或者条件表达式
params: dict/list of dict类型,传入单个字典时,使用适配器execute,多个executemany,参考适配器部分内容
返回参数: re
re: obj类型,返回的结果,ResultProxy结果代理类,可从中获取信息
E.g.:
result = session.execute(
user_table.select().where(user_table.c.id == 5)
) :meth:`~.Session.execute` accepts any executable clause construct,
such as :func:`~.sql.expression.select`,
:func:`~.sql.expression.insert`,
:func:`~.sql.expression.update`,
:func:`~.sql.expression.delete`, and
:func:`~.sql.expression.text`. Plain SQL strings can be passed
as well, which in the case of :meth:`.Session.execute` only
will be interpreted the same as if it were passed via a
:func:`~.expression.text` construct. That is, the following usage:: result = session.execute(
"SELECT * FROM user WHERE id=:param",
{"param":5}
) is equivalent to:: from sqlalchemy import text
result = session.execute(
text("SELECT * FROM user WHERE id=:param"),
{"param":5}
)
2.2.2.2.2.2 commit()方法
函数调用: ses.commit()
函数功能:提交会话事务(Flush pending changes and commit the current transaction),当没有待提交的事务时,会引起一个InvalidRequestError
传入参数: 无
返回参数: 无
2.2.2.2.2.3 close()方法
函数调用: ses.close()
函数功能:关闭会话
传入参数: 无
返回参数: 无
2.2.2.2.2.4 add()方法
函数调用: ses.add(instance)
函数功能:利用会话对象对表格添加数据
传入参数: instance
instance: obj类型,需要添加的表格信息对象
返回参数: 无
E.g.:
session.add(Table_name(id=6, name='Momo'))
2.2.2.2.2.5 add_all()方法
函数调用: ses.add_all(instances)
函数功能:利用会话对象对表格添加多项数据
传入参数: instances
instances: iterable类型,需要添加的表格信息可迭代对象
返回参数: 无
Note: 实际实现为for循环instances后利用add函数进行添加
2.2.2.2.2.6 query()方法
函数调用: qe = ses.query(*entities, **kwargs)
函数功能:利用会话对象对表格等数据进行查询操作,并返回一个新的Query对象
传入参数: *entities, **kwargs
entities: obj类型,需要查询的表格对象等
返回参数: qe
qe: obj类型,返回的Query对象
Note: 源代码的实现实际上是返回一个query.Query类实例
2.2.2.3 query模块
2.2.2.3.1 Query类
类实例化: qe = ses.query(*entities, **kwargs) / Query(entities, session=None)
类的功能:生成一个Query实例
传入参数: *entities, **kwargs
entities: obj类型,需要查询的表格对象等
返回参数: qe
qe: obj类型,返回的一个Query类实例
Link: http://docs.sqlalchemy.org/en/latest/orm/query.html
Note: 通常Query的实例化使用session.query()函数来返回,少数情况下也可直接通过Query类进行生成
E.g.:
qe = Query([User, Address], session=some_session)
# The above is equivalent to::
qe = some_session.query(User, Address)
2.2.2.3.1.1 filter()方法
函数调用: nqe = qe.filter(*criterion)
函数功能:根据标准进行条件筛选,并返回一个筛选后新的Query对象
传入参数: criterion
criterion: obj类型,条件查询表达式
返回参数: qe
qe: obj类型,返回的新Query对象
Note: 返回的是Query实例因此可以继续对其进行函数操作
E.g.:
# Single criteria
session.query(MyClass).filter(MyClass.name == 'some name') # Multiple criteria may be specified as comma separated; the effect
# is that they will be joined together using the :func:`.and_`
session.query(MyClass).filter(MyClass.name == 'some name', MyClass.id > 5)
2.2.2.3.1.2 filter_by()方法
函数调用: nqe = qe.filter(**kwargs)
函数功能:使用关键字表达式进行对象筛选
传入参数: kwargs
kwargs: obj类型,关键词条件查询表达式
返回参数: nqe
nqe: obj类型,返回的新Query对象
Note: 返回的是Query实例因此可以继续对其进行函数操作,关键字表达式会从首要的query对象中获取
E.g.:
# Single criteria
session.query(MyClass).filter_by(name == 'some name') # Multiple criteria may be specified as comma separated; the effect
# is that they will be joined together using the :func:`.and_`
session.query(MyClass).filter_by(name == 'some name', id > 5)
2.2.2.3.1.3 order_by()方法
函数调用: nqe = qe.order_by(*criterion)
函数功能:根据关键字进行排序
传入参数: criterion
criterion: obj类型,可传入某表列名
返回参数: nqe
nqe: obj类型,返回的新Query对象
2.2.3 .ext
2.2.3.1 ext.declarative模块
2.2.3.1.1 declarative_base()函数
函数调用: Base = declarative_base(**kwargs)
函数功能:为声明层的定义构建一个base类,基于Base类可以生成表格对象sqlalchemy.schema.Table,同时会使映射器函数sqlalchemy.orm.mapper调用时会提取类或其子类中的信息
传入参数: kwargs
返回参数: Base
Base: class类型,通常可以用作表格类的基类
2.2.4 .sql模块
2.2.4.1 sql.schema模块
2.2.4.1.1 Table类
类实例化:mytable = Table(name, metadata, **kwargs)
类的功能:用于映射表示一个数据库中的表
传入参数: name, metadata, kwargs
name: str类型,数据库中对应映射的表名称
metadata: obj类型,MetaData对象将包含这张表,metadata将作为这张表与其他表通过外键连接的关键点,可传入Base.metadata
column: obj类型,由Column类生成的列实例,用于对应表中的列
返回参数: mytable
mytable: instance类型,生成的表对象实例
E.g.:
mytable = Table("mytable", metadata,
Column('mytable_id', Integer, primary_key=True),
Column('value', String(50))
)
2.2.4.1.2 Column类
类实例化:mycolumn = Column(name, type, primary_key=, **kwargs)
类的功能:用于生成一个列的类实例
传入参数: name, type, primary, kwargs
name: str类型,数据库中表的列名称
type: obj类型,数据库中表的列存储数据类型
primary_key: bool类型,用于设置主键
返回参数: mycolumn
mycolumn: instance类型,生成的列对象实例
Note: 根据源码说明,在传入name和type之后,可直接传入其余SchemaItem类,诸如ForeignKey, Constraint等等
2.2.4.1.3 ForeignKey类
类实例化:fk= ForeignKey(column)
类的功能:用于生成外键
传入参数: column
column: obj/str类型,列的实例或列的名称
返回参数: fk
fk: instance类型,生成的外键实例对象
2.2.4.2 sql.sqltypes模块
2.2.4.2.1 Integer类
类实例化:无
类的功能:常用于列生成时传入的数据类型对象,等同于int/integers
传入参数: 无
返回参数: 无
2.2.4.2.2 VARCHAR类
类实例化:无
类的功能:常用于列生成时传入的数据类型对象,SQL VARCHAR类型
传入参数: string
string: str类型,VARCHAR的大小
返回参数: 无
2.2.5 .dialects模块
Note:
当在.sql.sqltype中找不到所需的数据类型时,可在此模块中进行获取,导入对于特定数据库,如MySQL, SQL Server等特有的数据类型的类对象进行使用
参考链接
https://stackoverflow.com/questions/30638003/connecting-to-database-using-sqlalchemy
http://blog.csdn.net/fgf00/article/details/52949973
http://www.cnblogs.com/liu-yao/p/5342656.html
http://docs.sqlalchemy.org/en/latest/orm/query.html
Python与数据库[2] -> 关系对象映射/ORM[0] -> ORM 与 sqlalchemy 模块的更多相关文章
- Python与数据库[2] -> 关系对象映射/ORM[5] -> 利用 sqlalchemy 实现关系表查询功能
利用 sqlalchemy 实现关系表查询功能 下面的例子将完成一个通过关系表进行查询的功能,示例中的数据表均在MySQL中建立,建立过程可以使用 SQL 命令或编写 Python 适配器完成. 示例 ...
- Python与数据库[2] -> 关系对象映射/ORM[1] -> sqlalchemy 的基本使用示例
sqlalchemy 的基本使用示例 下面的例子中将利用sqlalchemy进行数据库的连接,通过orm方式利用类实例属性操作的方式对数据库进行相应操作,同时应用一些常用的函数. 完整代码如下: fr ...
- Python与数据库[2] -> 关系对象映射/ORM[3] -> sqlalchemy 的声明层 ORM 访问方式
sqlalchemy的声明层ORM访问方式 sqlalchemy中可以利用声明层进行表格类的建立,并利用ORM对象进行数据库的操作及访问,另一种方式为显式的 ORM 访问方式. 主要的建立步骤包括: ...
- Python与数据库[2] -> 关系对象映射/ORM[4] -> sqlalchemy 的显式 ORM 访问方式
sqlalchemy 的显式 ORM 访问方式 对于sqlalchemy,可以利用一种显式的ORM方式进行访问,这种方式无需依赖声明层,而是显式地进行操作.还有一种访问方式为声明层 ORM 访问方式. ...
- Python与数据库[2] -> 关系对象映射/ORM[2] -> 建立声明层表对象的两种方式
建立声明层表对象的两种方式 在对表对象进行建立的时候,通常有两种方式可以完成,以下是两种方式的建立过程对比 首先导入需要的模块,获取一个声明层 from sqlalchemy.sql.schema i ...
- 一:ORM关系对象映射(Object Relational Mapping,简称ORM)
狼来的日子里! 奋发博取 10)django-ORM(创建,字段类型,字段参数) 一:ORM关系对象映射(Object Relational Mapping,简称ORM) ORM分两种: DB fir ...
- 关系/对象映射 多对多关系(@ManyToMany 注释)【重新认识】
old: @ManyToMany 注释:表示此类是多对多关系的一边, mappedBy 属性定义了此类为双向关系的维护端, 注意:mappedBy 属性的值为此关系的另一端的属性名. 例如,在Stud ...
- ORM 关系对象映射 基础知识点
优点: 1.ORM使我们通用的数据库变得更加的简单便捷. 2.可避免新手程序员写sql语句带来的性能问题. 1. 创建单表 2. 创建关键表 1). 一对一 2). 一对多 3). 多对多 创建表的语 ...
- django关系对象映射(Object Relational Mapping,简称ORM)
Model 创建数据库,设计表结构和字段 django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表 from django.db import models clas ...
随机推荐
- 《Cracking the Coding Interview》——第7章:数学和概率论——题目3
2014-03-20 02:05 题目:给定笛卡尔二维平面上两条直线,判断它们是否相交. 解法:相交.重合.平行. 代码: // 7.3 Given two lines on the Cartesia ...
- 《数据结构》C++代码 堆(优先队列)
堆,是优先队列最常用的一种实现方式.在优先队列中,每个元素都被赋予了一个优先级,而每次出队时都让优先级最高的元素出队.堆,则是一种存储优先队列的方法,特指以一棵树形式存储的优先队列.最常用的是二叉堆, ...
- 【Linear Models for Binary Classification】林轩田机器学习基石
首先回顾了几个Linear Model的共性:都是算出来一个score,然后做某种变化处理. 既然Linear Model有各种好处(训练时间,公式简单),那如何把Linear Regression给 ...
- Python 爬取网页中JavaScript动态添加的内容(一)
当我们进行网页爬虫时,我们会利用一定的规则从返回的 HTML 数据中提取出有效的信息.但是如果网页中含有 JavaScript 代码,我们必须经过渲染处理才能获得原始数据.此时,如果我们仍采用常规方法 ...
- 出现java.lang.IllegalArgumentException异常
严重: Servlet.service() for servlet [office] in context with path [/office] threw exception [Request p ...
- pin
sjhh@123456 Michael zhang zhangxiaocong_2011@yeah.net
- android瀑布流照片墙实现代码详解
照片墙的实现,是需要往手机里面添加很多图片的,如果没有对资源进行合理的释放,程序很快就会出现OOM.所以需要用到LruCache算法来缓存图片. 1,首先是图片资源类,这个类中包含了很多图片链接. p ...
- asp.net 存储过程 输出参数 取不到值
这是MSDN上的明确解释:当您将 Command 对象用于存储过程时,可以将 Command 对象的 CommandType 属性设置为 StoredProcedure.当 CommandType 为 ...
- 洛谷 P3349 [ZJOI2016]小星星 解题报告
P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...
- swipe display: none后再显示,加载内容后,滑动失效问题
只需要添加这两个属性即可: observer:true,//修改swiper自己或子元素时,自动初始化swiper observeParents:true//修改swiper的父元素时,自动初始化sw ...