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),即对 ...
随机推荐
- 开源WebGIS实施方案(六):空间数据(PostGIS)与GeoServer服务迁移
研发环境的变更,或者研发完成进行项目现场实施.运维的时候,经常就会面临数据及服务的迁移,这其中就包含空间数据以及GeoServer服务的迁移工作. 这里需要提醒的是:如果采用的是类似的开源WebGIS ...
- Backbone学习笔记 - Model篇
2 Model 在Backbone中,Model用于存储核心数据,可以将数据交互相关的逻辑代码放在这里.基本形式如下: var Human = Backbone.Model.extend({ init ...
- 第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock()
最常用的方式: int a = 12; //注意:通常情况下,这个会设置成一个类变量,比如说Segement中的段锁与copyOnWriteArrayList中的全局锁 final Reentrant ...
- 一文看尽 Raft 一致性协议的关键点
本文由 网易云 发布. 作者:孙建良 Raft 协议的发布,对分布式行业是一大福音,虽然在核心协议上基本都是师继 Paxos 祖师爷(Lamport) 的精髓,基于多数派的协议.但是 Raft 一致 ...
- C语言 IPv6 十六进制 转 十进制
#include <stdio.h> #include <string.h> #include <math.h> //ipv4地址转换 int ipv4_to_i( ...
- rocketmq学习
官网地址 安装name server和broker git clone https://github.com/apache/incubator-rocketmq.git cd incubator-ro ...
- Webstorm 的 Tab 键怎样调整缩进值? 调节成缩进成2个空格或者4个空格
原文:https://blog.csdn.net/niexia_/article/details/78280569 需求:因为用了eslint,对代码格式很严格.统一用空格.而用tab方式会省事很多. ...
- (6)Oracle基础--简单查询
.基本查询语句 SELECT [DISTINCT] column_name1,... | * FROM table_name [WHERE conditions]; P: DISTINCT关键字的作 ...
- vue 学前班003(生命周期)
ue把整个生命周期划分为创建.挂载.更新.销毁等阶段,每个阶段都会给一些“钩子”让我们来做一些我们想实现的动作.学习实例的生命周期,能帮助我们理解vue实例的运作机制,更好地合理利用各个钩子来完成我们 ...
- 00-python概述。
人生苦短,我用Python. -发展历史: - 1989年,由Guido van Rossum开始开发, - 1991年,发布第一个公开发行版,第一个Python编译器(同时也是解释器)诞生. - 2 ...