Python与数据库[2] -> 关系对象映射/ORM -> 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的优点:

  1. 隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。
  2. 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:[email protected]:port/database‘  

而在1.0以上的版本中则需要对驱动进行指定,

connection = ‘mssql+pyodbc://username:[email protected]: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.:

1 from sqlalchemy.ext.declarative import declarative_base
2
3 Base = declarative_base()
4
5 class Parent(Base):
6     __tablename__ = ‘parent‘
7     id = Column(Integer, primary_key=True)
8     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.:

1 # global scope
2 Session = sessionmaker(autoflush=False)
3 # later, in a local scope, create and use a session:
4 sess = Session()
5 # Any keyword arguments sent to the constructor itself will override the
6 # "configured" keywords::
7 Session = sessionmaker()
8 # bind an individual session to a connection
9 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等特有的数据类型的类对象进行使用

参考链接


http://www.sqlalchemy.org/

https://stackoverflow.com/questions/30638003/connecting-to-database-using-sqlalchemy

https://stackoverflow.com/questions/30025509/sqlalchemy-orm-styles-how-to-make-special-drive-to-your-connection-string

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

原文地址:https://www.cnblogs.com/stacklike/p/8179171.html

时间: 2024-10-08 18:00:32

Python与数据库[2] -> 关系对象映射/ORM -> ORM 与 sqlalchemy 模块的相关文章

Python与数据库[2] -> 关系对象映射/ORM -> 利用 sqlalchemy 实现关系表查询功能

利用 sqlalchemy 实现关系表查询功能 下面的例子将完成一个通过关系表进行查询的功能,示例中的数据表均在MySQL中建立,建立过程可以使用 SQL 命令或编写 Python 适配器完成. 示例中用到的表主要有3张,一张personInfo个人信息表,一张account_store账号信息表,以及一张person_account_rel的个人信息与账号关系表. 示例中将会通过已知的人物年龄和id通过个人信息表查出个人姓名(仅为参考示例,请忽略怪异的查找逻辑 :) ),随后根据关系表得到的人

Python与数据库[2] -> 关系对象映射/ORM -> sqlalchemy 的基本使用示例

sqlalchemy 的基本使用示例 下面的例子中将利用sqlalchemy进行数据库的连接,通过orm方式利用类实例属性操作的方式对数据库进行相应操作,同时应用一些常用的函数. 完整代码如下: 1 from sqlalchemy import create_engine, exc, orm 2 from sqlalchemy.ext.declarative import declarative_base 3 from sqlalchemy.sql.schema import Table, Fo

一:ORM关系对象映射(Object Relational Mapping,简称ORM)

狼来的日子里! 奋发博取 10)django-ORM(创建,字段类型,字段参数) 一:ORM关系对象映射(Object Relational Mapping,简称ORM) ORM分两种: DB first 先在数据库中创建数据库表等 Code first 先创建类,然后根据类创建数据表等.django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表. 二:Django ORM创建 1)创建类 创建的类必须继承models.Model,在数据库中自动创建表名为:app

关系对象映射

ORM(object relationalMapping) 对象是一个内存结构,与关系数据型数据库中的记录从逻辑上说存在映射关系,但是从存储关系上说面向对象与关系型数据库存在互不匹配现象,对象关系映射是为了解决这种不匹配现象的技术,它通过描述对象和数据库之间映射关系的元素,将java程序中的对象自动持久化到关系数据库中,反过来讲数据库中的记录自动的读取到内存结构对象中. 对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据..内存中的对象之间存在关联和继承

关系/对象映射 多对多关系(@ManyToMany 注释)【重新认识】

old: @ManyToMany 注释:表示此类是多对多关系的一边, mappedBy 属性定义了此类为双向关系的维护端, 注意:mappedBy 属性的值为此关系的另一端的属性名. 例如,在Student类中有如下方法: 被控方: @ManyToMany(fetch = FetchType.LAZY, mappedBy = "students") public Set<Teacher> getTeachers() { return teachers; } 那么这里的“st

ORM(关系对象映射)框架之面向对象

1. 提取共性 2. 分类 3. 模板"约束" 4. 当一类函数公用同样参数时候,可以转变成类进行 - 分类 3. 面向对象: 数据和逻辑(属性和行为)组合在一起    函数编程:数据和逻辑分离 1 特殊方法: 2 class Foo: 3 def __init__(self,name): 4 self.name = name 5 6 7 def show(self): 8 print(self.name) 9 10 def __call__(self): 11 pass 12 13

django关系对象映射(Object Relational Mapping,简称ORM)

Model 创建数据库,设计表结构和字段 django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表 from django.db import models class userinfo(models.Model): name = models.CharField(max_length=30) email = models.EmailField() memo = models.TextField() 连表结构 一对多:models.ForeignKey(其他表)

python 全栈 数据库 (三) python操作数据库

python 操作MYSQL数据库主要有两种方式: 使用原生模块:pymysql ORM框架:SQLAchemy 一.pymysql 1.1下载安装模块 第一种:cmd下:执行命令下载安装:pip3 install pymysql 第二种:IDE下pycharm python环境路径下添加模块 1.2使用操作 #导入模块 import pymysql #建立连接通道,建立连接填入(连接数据库的IP地址,端口号,用户名,密码,要操作的数据库,字符编码) conn = pymysql.connect

python操作数据库 - SQLAlchemy

ORM简介 ORM全称是Object Relational Mapping(关系对象映射).实质是将关系数据库中的业务数据用对象的形式表示出来,并通过面向对象的方式将这些对象组织起来,最终在应用中创建一个虚拟对象数据库. 核心就是一个class对应一张表. SQLAlchemy现在已经是python中最流行的ORM框架. ORM优点: 1.隐藏数据库实现,让业务代码只访问对象而不是数据库表 2.良好的数据库操作接口,简单.学习成本低 3.动态数据表映射,表结构改变时,减少代码修改量 4.方便引入