ORM是建立在SQL语言构造器之上的工具集,用于将Python对象映射到数据库的行,提供了一系列接口用于从数据库中存取对象(行)。在ORM 工作时,在底层调用SQL语言构造器的API,这些通用的操作有些许的不同。不同的是,你不再使用行,而是使用自定义类的对象来操作。另外,数据库的查询 方式也不同,ORM的可以生成大多数的SQL查询,除此之外还可以在类中定义更多操作
1)检查sqlalchemy版本
>>> import sqlalchemy >>> sqlalchemy.__version__ '1.2.0b2'
2) 建立连接connecting
>>> from sqlalchemy import create_engine >>> engine=create_engine("mysql+pymysql://admin:admin@192.168.6.22/coursesys?charset=utf8",encoding="utf-8",echo=True) 1)通过create_engine()建立连接,create_engine是 Engine实例,create_engine第一次调用的时候会调用Engine.execute()或者 Engine.connect()方法, 通过dialect在数据库和DBAPI之间建立连接关系。 注意:返回create_engine对象并没有连接到数据库。只有在执行第一次要求对数据库时才连接 2)echo是SQLAlchemy logging 是个标准logging模型。当echo 为True看到所有生成的SQL;希望少输出,设置它 False 3)mysql+pymysql://admin:admin@192.168.6.22/coursesys?charset=utf8 是个dialect连接 4)engine=create_engine('sqlite:///:memory:',echo=True)将使用一个只在内存中SQLite数据库
3)声明映射
我们使用ORM:映射类与数据库表。SQLAlchemy在中首先通过declarative_base申明一个基类。这个基类维持着类与数据库表的关系
>>> from sqlalchemy.ext.declarative import declarative_base >>> Base=declarative_base()
声明表第一种方式:在自定义类继承declarative_base这个基类来映射数据表
>>> class User(Base): __tablename__="users" id=Column(Integer,primary_key=True) name=Column(String) fullname=Column(String) password=Column(String) def __repr__(self): return "User(name=%s,fullname=%s,password=%s" %(self.name,self.fullname,self.password)
__tablename__指定表名
Column 指定字段
primary_key 设置主键
__repr__ 当打印User对象时显示的数据。
声明表第二种方式:通过模式声明,通过__table__可以查看定义表元数据。
from sqlalchemy import Table, MetaData, Column, Integer, String, ForeignKey from sqlalchemy.orm import mapper metadata = MetaData() user = Table('user', metadata, Column('id', Integer, primary_key=True), Column('name', String(50)), Column('fullname', String(50)), Column('password', String(12)) ) class User(object): def __init__(self, name, fullname, password): self.name = name self.fullname = fullname self.password = password mapper(User, user)
>>> User.__table__ Table('users', MetaData(bind=None), Column('id', Integer(), table=<users>, prima ry_key=True, nullable=False), Column('name', String(), table=<users>), Column('f ullname', String(), table=<users>), schema=None)
MetaData是一个注册表包括能够一组执行的命令到数据库,上面声明了表的类,但是数据库中并没有创建表,
通过Base.metadata.create_all(engine)向数据库发出建表完成类与表的映射
4)建立表
>>Base.metadata.create_all(engine) 2017-08-17 14:51:37,117 INFO sqlalchemy.engine.base.Engine SELECT CAST('test pla in returns' AS VARCHAR(60)) AS anon_1 2017-08-17 14:51:37,117 INFO sqlalchemy.engine.base.Engine () 2017-08-17 14:51:37,117 INFO sqlalchemy.engine.base.Engine SELECT CAST('test uni code returns' AS VARCHAR(60)) AS anon_1 2017-08-17 14:51:37,117 INFO sqlalchemy.engine.base.Engine () 2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("us ers") 2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine () 2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine CREATE TABLE users ( id INTEGER NOT NULL, name VARCHAR, fullname VARCHAR, PRIMARY KEY (id) ) 2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine () 2017-08-17 14:51:37,133 INFO sqlalchemy.engine.base.Engine COMMIT
5)字段长度
在上面的String中我们并没有指明长度,在SQLite和PostgreSQL是有效的,但是在mysql等中String,Integer, Numeric等会报错需要指定长度
Column(String(50))
在oracleo等数据库中,有可能需要用到序列,你可以通过Sequence来使用
from sqlalchemy import Sequence
Column(Integer, Sequence('user_id_seq'), primary_key=True)
class User(Base): __tablename__ = 'users' id = Column(Integer, Sequence('user_id_seq'), primary_key=True) name = Column(String(50)) fullname = Column(String(50)) password = Column(String(12)) def __repr__(self): return "<User(name='%s', fullname='%s', password='%s')>" % ( self.name, self.fullname, self.password)
6)建立会话
1)通过 Session处理ORM和数据表。
两种方式:声明并绑定engine
>>> from sqlalchemy.orm import sessionmaker >>> Session = sessionmaker(bind=engine)
2) 如果还没有engine,先创建engine,在通过configure绑定到session
Session = sessionmaker()
Session.configure(bind=engine)
上面通过sessionmaker创建是一个类,需要实例类
session=Session()
7)增加修改数据
>>> ed_user=User(name="ed",fullname="ed Jone") >>> session.add(ed_user)
8)获取自曾ID
ed_user.id
9)查看数据
>>> our_user = session.query(User).filter_by(name='ed').first() >>> our_user <User(name='ed', fullname='Ed Jones', password='edspassword'
10)修改数据
ed_user.fullname = '11111'
session.dirty 修改数据后,数据变为脏数据,可以通过dirty查看
IdentitySet([<User(name='ed', fullname='11111'>])
11)增加一组数据
session.add_all([ ... User(name='wendy', fullname='Wendy Williams'), ... User(name='mary', fullname='Mary Contrary'), ... User(name='fred', fullname='Fred Flinstone']) session.new #表示查看新增加的数据 IdentitySet([<User(name='wendy', fullname='Wendy Williams', password='foobar')>, <User(name='mary', fullname='Mary Contrary', password='xxg527')>, <User(name='fred', fullname='Fred Flinstone', password='blah')>])
12) 提交数据回滚数据
上面的数据并没有在数据库中,需要通过commit()方法把数据提交到数据库中,获取通过rollback回滚数据。
commit()确认数据
Session.rollback()回滚数据。 mysql> select * from users; Empty set (0.00 sec) sesstion.commit() mysql> select * from users; +----+------+----------+----------+ | id | name | fullname | password | +----+------+----------+----------+ | 1 | shi | shi jun | 123456 | +----+------+----------+----------+ 1 row in set (0.00 sec)
# -*- coding:utf-8 -*-
__author__ = 'shisanjun'
import sqlalchemy
from sqlalchemy import Column,Integer,String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
#创建连接
engine=sqlalchemy.create_engine("mysql+pymysql://admin:admin@192.168.0.121/test2?charset=utf8",echo=True)
#声明ORM映射基类
BASE=declarative_base()
class User(BASE):
__tablename__="users" #指定表名
id=Column(Integer,primary_key=True) #建立主键
name=Column(String(32))
fullname=Column(String(32))
password=Column(String(32))
def __repr__(self): #返回对象时打印显示
return "name:%s full name:%s password:%s" %(self.name,self.fullname,self.password)
#向数据库发出建表,完成类与表的映射,在数据库中生成所有继承declarative_base表
BASE.metadata.create_all(bind=engine)
#声明会话类
Session=sessionmaker(bind=engine)
#实例化会话类
session=Session()
#增加数据
user1=User(name="ed",fullname="ed jone",password="123456")
#增加一条数据
session.add(user1)
#查看自增ID号
print(user1.id)
#增加多条数据
session.add_all([
User(name="shi",fullname="shi jone",password="123456"),
User(name="san",fullname="san jone",password="123456"),
User(name="jun",fullname="jun jone",password="123456"),
])
#查看新增数据
print(session.new)
#修改数据
user1.fullname="tianshi"
#查看脏数据
print(session.dirty)
#上面的数据并没有提交到数据库中,数据还在内存中
#把sesstion事务数据提交到数据库中
session.commit()
#把数据从session事务中剔除
#session.rollback()