SQLAlchemy使用说明之ORM
对象关系映射(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的更多相关文章
- Python3+SQLAlchemy+Sqlite3实现ORM教程
一.安装 Sqlite3是Python3标准库不需要另外安装,只需要安装SQLAlchemy即可.本文sqlalchemy版本为1.2.12 pip install sqlalchemy 二.ORM操 ...
- 灵活使用 SQLAlchemy 中的 ORM 查询
之前做查询一直觉得直接拼 SQL 比较方便,用了 SQLAlchemy 的 ORM 查询之后,发现也还可以,还提高了可读性. 这篇文章主要说说 SQLAlchemy 常用的 ORM 查询方式,偏实践. ...
- sqlalchemy的数据库ORM操作(表之间的关系)
首先导入一些需要的东东 ,我是在flask中写的,也可以用纯python去写. from flask import Flask from sqlalchemy import create_engine ...
- 冰冻三尺非一日之寒-mysql(orm/sqlalchemy)
第十二章 mysql ORM介绍 2.sqlalchemy基本使用 ORM介绍: orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似pyt ...
- Python-12-MySQL & sqlalchemy ORM
MySQL MySQL相关文章这里不在赘述,想了解的点击下面的链接: >> MySQL安装 >> 数据库介绍 && MySQL基本使用 >> MyS ...
- 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 ...
- Django和SQLAlchemy,哪个Python ORM更好?
ORM是什么? 在介绍Python下的两个ORM框架(Django和SQLAlchemy)的区别之前,我们首先要充分了解ORM框架的用途. ORM代表对象关系映射.ORM中的每个单词解释了他们在实际项 ...
- SQLAlchemy的ORM
表关系: 表之间的关系存在三种:一对一.一对多.多对多.而SQLAlchemy中的ORM也可以模拟这三种关系.因为一对一其实在SQLAlchemy中底层是通过一对多的方式模拟的,所以先来看下一对多的关 ...
- Python与数据库[2] -> 关系对象映射/ORM[0] -> ORM 与 sqlalchemy 模块
ORM 与 sqlalchemy 1 关于ORM / About ORM 1.1 ORM定义 / Definition of ORM ORM(Object Relational Mapping),即对 ...
随机推荐
- WPF 打印崩溃问题( 异常:Illegal characters in path/路径中有非法字符)
现象: 打印时候程序直接崩溃.调试时出现下列异常. 异常信息: 中文:System.ArgumentException : 路径中有非法字符. 英文: System.ArgumentException ...
- js图片自适应尺寸居中函数处理
/* | autoSerializePicture.js 自适应格式化图片 | auther : baichaohua/2017-09-21 +---------------------------- ...
- JEECG(二) JEECG框架下调用webservice java springmvc maven 调用 webservice
JEECG系列教程二 如何在JEECG框架下使用webservice 本文所使用的webservice是c#开发的 其实无论是什么语言开发的webservice用法都一样 java springmvc ...
- sql表与表之间的数据操作
--把一张表的内容更新到另一张表 update 表1 set 表1.Store=t2.Name from 表2 t2 where 表1.id=t2.id --备份一张表 create table ta ...
- EF简易教程,从建表到表间关系
唐大兵博客 唐大兵的博客里记录了EF Code First从建表到表之间关系的详细内容. 汪杰的博客(EF里一对一.一对多.多对多关系的配置和级联删除) 汪杰的博客更简洁,但不够充实,读懂了唐大兵博客 ...
- .NET Core中使用Dapper操作Oracle存储过程最佳实践
为什么说是最佳实践呢?因为在实际开发中踩坑了,而且发现网上大多数文章给出的解决方法都不能很好地解决问题.尤其是在获取类型为OracleDbType.RefCursor,输出为:ParameterDir ...
- 名词-JS
1: 构造函数的伪装.(JS继承的时候出现 通过call函数改变this指向的对象) 2: 原型链.(JS继承的时候出现) 3:宿主对象:(有浏览器提供的对象.DOM, BOM - Document ...
- 浅谈对MVC的认识
MVC是model(模型),view(视图),Controller(控制)的缩写. 模型层负责提供数据,和数据库相关的操作都交给模型层处理: 视图层提供交互的界面,其输出数据: 控制层负责接收各种请求 ...
- C++中new申请动态数组
C++中数组分为静态数组和动态数组,静态数组必须确定数组的大小,不然编译错误:而动态数组大小可以不必固定,用多少申请多少.静态数组类于与我们去餐馆吃饭,餐馆会把菜做好.而动态数组类似于我们自己买菜做饭 ...
- SSL学习笔记
/************************************数据类型***************************************//* Number(数值型),Bool ...