对象关系映射(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. 微软发布TFS 2018!

    也许你还没来得及使用TFS 2017,今天,微软已经发布了TFS 2018的第一个版本(RC1). 与之前所有的候选版本一样,这是一个正式上线(微软成称为go-live)的TFS版本.如果你计划采纳T ...

  2. C#开发微信小程序

    个人见解,欢迎交流,不喜勿喷.   微信小程序相比于微信公众号的开发,区别在于微信小程序只请求第三方的数据,整个界面的交互(view)还是在微信小程序上实现,前后端完全分离,说白了,微信小程序开发与具 ...

  3. Extjs文件上传问题总结

    本来文件上传是一个简单而常用的功能,但是,由于刚刚接触extjs,对extjs中的控件及其使用方法并不熟悉,导致本来一个很快就可以搞定的文件上传问题,弄了将近两天的时间.现将问题及解决办法发出来,供有 ...

  4. (C#)调用Webservice,提示远程服务器返回错误(500)内部服务器错误

    因为工作需要调用WebService接口,查了下资料,发现添加服务引用可以直接调用websevice 参考地址:https://www.cnblogs.com/peterpc/p/4628441.ht ...

  5. C#如何关闭指定进程

    public static void KillProcess(string strProcessesByName)//关闭线程 { foreach (Process p in Process.GetP ...

  6. 在sqlite中,如何删除字段? how to drop a column in sqlite

    在sqlite中可以使用ALTER TABLE语法对表结构进行修改,从官方的文档说明中,语法如下图: 从图中可以看出,ALTER TABLE仅仅支持表名重命名,添加字段,却没有删除字段的方法.那么该如 ...

  7. AOP面向切面的基石——动态代理(一)

    其实动态代理在Java里不是什么新技术了,早在java 1.2之后便通过 java.lang.reflect.InvocationHandler 加入了动态代理机制. 下面例子中,LancerEvol ...

  8. S11 day 93 RestFramework 之 序列化

    1. 表建模 from django.db import models # Create your models here. #文章表 class Article(models.Model): tit ...

  9. Day6 ,周期末考试试题

    Python基础数据类型考试题 考试时间:两个半小时                      满分100分(80分以上包含80分及格) 一,基础题. 1,简述变量命名规范(3分) 2,字节和位的关系 ...

  10. “全栈2019”Java多线程第二十章:同步方法产生死锁的例子

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...