对象关系映射(Object Relation Map, ORM)可以将一个类映射为关系模式(数据表). 使用ORM比直接书写SQL在安全性,可读性上都有很大优势.

Working with Related Objects

下面的示例展示如何使用ORM定义一个关系模式并进行实例化.

from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
import MySQLdb from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base):
__tablename__ = 'user'
user_id = Column('user_id', Integer, primary_key=True)
name = Column('name', String(20))
fullname = Column('fullname', String(20)) def __repr__(self):
return "<User(user_id='%d', name='%s'), fullname='%s'>" % (self.user_id, self.name, self.fullname) def get_session():
engine = create_engine("mysql://root:248536@localhost:3306/test?charset=utf8", encoding="utf-8", echo=True)
mysql_session_maker = sessionmaker(bind=engine)
session = mysql_session_maker()
return session if __name__ == '__main__':
session = get_session()
user = User(user_id=1, name='finley', fullname='finley ?')
session.add(user)
session.commit()
user = User(user_id=2, name='finley2', fullname='finley ?')
session.add(user)
session.rollback()
user = User(user_id=3, name='finley3', fullname='finley ?')
session.add(user)
session.commit()
session.close()

终端回显:

INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
INFO sqlalchemy.engine.base.Engine INSERT INTO user (user_id, name, fullname) VALUES (%s, %s, %s)
INFO sqlalchemy.engine.base.Engine (1, 'finley', 'finley ?')
INFO sqlalchemy.engine.base.Engine COMMIT
INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
INFO sqlalchemy.engine.base.Engine INSERT INTO user (user_id, name, fullname) VALUES (%s, %s, %s)
INFO sqlalchemy.engine.base.Engine (3, 'finley3', 'finley ?')
INFO sqlalchemy.engine.base.Engine COMMIT

上述示例展示了通过ORM和session进行事务操作(implicit transcation).

通过metadata创建表:

Base.metadata.create_all(engine)

rollback()可以回滚到上次commit.

通过session进行事务性操作, 注意那些复杂的工厂.

Add & Remove

生成实例后用session进行添加或者删除操作:

user = User(user_id=1, name='finley', fullname='finley ?')
session.add(user)
session.commit()

删除操作类似, 注意User实例通过查询数据库获得:

user = session.query(User).filter(User.user_id == 1)[0]
session.delete(user)
session.commit()

Query

首先做一个全查询:

result = session.query(User)
session.commit()
session.close()
# print result
print(result)
for instance in result:
print(instance)

返回的结果:

INFO sqlalchemy.engine.base.Engine   SELECT
user.user_id AS user_user_id,
user.name AS user_name,
user.fullname AS user_fullname
FROM user INFO sqlalchemy.engine.base.Engine ()
<User(user_id='1', name='finley'), fullname='finley ?'>
<User(user_id='3', name='finley3'), fullname='finley ?'>

也可以很方便的指定要查询的列:

result = session.query(User.user_id, User.name)

结果:

(1L, u'finley')
(3L, u'finley3')

ORM使用filter来筛选记录:

>>> result = session.query(User.user_id, User.name).filter(User.user_id == 1).all()
>>>session.commit()
>>>session.close()
>>>
>>>print(result)
[(1L, u'finley')]

query对象使用和select类似的运算符, filter可以链式调用并支持order_by()等功能.

更多黑魔法请参见

Relationship

Many to One

Relationship用来维护两个数据表之间的关系, 含有Relationship的表需要使用外键指定参照关系:

from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
import MySQLdb from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref Base = declarative_base() class User(Base):
__tablename__ = 'user'
user_id = Column('user_id', Integer, primary_key=True)
name = Column('name', String(20))
fullname = Column('fullname', String(20))
def __repr__(self):
return "<User(user_id='%d', name='%s', fullname='%s')>" % (self.user_id, self.name, self.fullname) class Address(Base):
__tablename__ = 'address'
address_id = Column('address_id', Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('user.user_id'))
user = relationship("User", backref=backref('addresses'))
def __repr__(self):
return "<Address(address_id='%d', user_id='%d')>" % (self.address_id, self.user_id) def get_session():
engine = create_engine("mysql://root:248536@localhost:3306/test?charset=utf8", encoding="utf-8", echo=True)
mysql_session_maker = sessionmaker(bind=engine)
session = mysql_session_maker()
return session if __name__ == '__main__':
session = get_session()
# add by user
user = User(user_id=1, name='finley', fullname='finley ?')
user.addresses = [
Address(address_id=1, user_id=1),
Address(address_id=2, user_id=1)
]
session.add(user);
# add by address
address = Address(address_id=3, user_id=1)
session.add(address)
session.commit()
# query relationship
result = session.query(User).filter(User.user_id == 1)
for i in result:
print(i.addresses)
session.close()

反向索引backref使得User实例可以查询与其关联的address:

user.addresses

添加关系可以直接操作Address表:

address = Address(address_id=3, user_id=1)
session.add(address) # session.remove(address)
session.commit()

也可以通过User的backref:

    user = User(user_id=1, name='finley', fullname='finley ?')
user.addresses = [
Address(address_id=1, user_id=1),
Address(address_id=2, user_id=1)
]
session.add(user);

删除操作类似, 不过因为Foreign Key约束的存在, 需要费点事.

(我不会说自己用删除user记录重新添加的方法的)

Many to Many

sqlalchemy docs - ORM - Many to Many Relationship

SQLAlchemy使用说明之ORM的更多相关文章

  1. Python3+SQLAlchemy+Sqlite3实现ORM教程

    一.安装 Sqlite3是Python3标准库不需要另外安装,只需要安装SQLAlchemy即可.本文sqlalchemy版本为1.2.12 pip install sqlalchemy 二.ORM操 ...

  2. 灵活使用 SQLAlchemy 中的 ORM 查询

    之前做查询一直觉得直接拼 SQL 比较方便,用了 SQLAlchemy 的 ORM 查询之后,发现也还可以,还提高了可读性. 这篇文章主要说说 SQLAlchemy 常用的 ORM 查询方式,偏实践. ...

  3. sqlalchemy的数据库ORM操作(表之间的关系)

    首先导入一些需要的东东 ,我是在flask中写的,也可以用纯python去写. from flask import Flask from sqlalchemy import create_engine ...

  4. 冰冻三尺非一日之寒-mysql(orm/sqlalchemy)

    第十二章  mysql ORM介绍    2.sqlalchemy基本使用 ORM介绍: orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似pyt ...

  5. Python-12-MySQL & sqlalchemy ORM

    MySQL MySQL相关文章这里不在赘述,想了解的点击下面的链接: >> MySQL安装 >> 数据库介绍 && MySQL基本使用 >> MyS ...

  6. Python’s SQLAlchemy vs Other ORMs[转发 3]Django's ORM

    Django's ORM Django is a free and open source web application framework whose ORM is built tightly i ...

  7. Django和SQLAlchemy,哪个Python ORM更好?

    ORM是什么? 在介绍Python下的两个ORM框架(Django和SQLAlchemy)的区别之前,我们首先要充分了解ORM框架的用途. ORM代表对象关系映射.ORM中的每个单词解释了他们在实际项 ...

  8. SQLAlchemy的ORM

    表关系: 表之间的关系存在三种:一对一.一对多.多对多.而SQLAlchemy中的ORM也可以模拟这三种关系.因为一对一其实在SQLAlchemy中底层是通过一对多的方式模拟的,所以先来看下一对多的关 ...

  9. Python与数据库[2] -> 关系对象映射/ORM[0] -> ORM 与 sqlalchemy 模块

    ORM 与 sqlalchemy 1 关于ORM / About ORM 1.1 ORM定义 / Definition of ORM ORM(Object Relational Mapping),即对 ...

随机推荐

  1. 开源WebGIS实施方案(六):空间数据(PostGIS)与GeoServer服务迁移

    研发环境的变更,或者研发完成进行项目现场实施.运维的时候,经常就会面临数据及服务的迁移,这其中就包含空间数据以及GeoServer服务的迁移工作. 这里需要提醒的是:如果采用的是类似的开源WebGIS ...

  2. Backbone学习笔记 - Model篇

    2 Model 在Backbone中,Model用于存储核心数据,可以将数据交互相关的逻辑代码放在这里.基本形式如下: var Human = Backbone.Model.extend({ init ...

  3. 第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()

    最常用的方式: int a = 12; //注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁与copyOnWriteArrayList中的全局锁 final Reentrant ...

  4. 一文看尽 Raft 一致性协议的关键点

    本文由  网易云 发布. 作者:孙建良 Raft 协议的发布,对分布式行业是一大福音,虽然在核心协议上基本都是师继 Paxos 祖师爷(Lamport) 的精髓,基于多数派的协议.但是 Raft 一致 ...

  5. C语言 IPv6 十六进制 转 十进制

    #include <stdio.h> #include <string.h> #include <math.h> //ipv4地址转换 int ipv4_to_i( ...

  6. rocketmq学习

    官网地址 安装name server和broker git clone https://github.com/apache/incubator-rocketmq.git cd incubator-ro ...

  7. Webstorm 的 Tab 键怎样调整缩进值? 调节成缩进成2个空格或者4个空格

    原文:https://blog.csdn.net/niexia_/article/details/78280569 需求:因为用了eslint,对代码格式很严格.统一用空格.而用tab方式会省事很多. ...

  8. (6)Oracle基础--简单查询

    .基本查询语句  SELECT [DISTINCT] column_name1,... | * FROM table_name [WHERE conditions]; P: DISTINCT关键字的作 ...

  9. vue 学前班003(生命周期)

    ue把整个生命周期划分为创建.挂载.更新.销毁等阶段,每个阶段都会给一些“钩子”让我们来做一些我们想实现的动作.学习实例的生命周期,能帮助我们理解vue实例的运作机制,更好地合理利用各个钩子来完成我们 ...

  10. 00-python概述。

    人生苦短,我用Python. -发展历史: - 1989年,由Guido van Rossum开始开发, - 1991年,发布第一个公开发行版,第一个Python编译器(同时也是解释器)诞生. - 2 ...