python之SQLAlchemy ORM 上
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python之SQLAlchemy ORM 上相关的知识,希望对你有一定的参考价值。
前言: SQLAlchmey是暑假学的,当时学完后也没及时写博客整理下。这篇博客主要介绍下SQLAlchemy及基本操作,写完后有空做个堡垒机小项目。下篇博客整理写篇关于Web框架和django基础~~
一、ORM介绍
orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了保证一致的使用习惯,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sql语言。
orm的优点:
- 隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。
- ORM使我们构造固化数据结构变得简单易行。
缺点:
- 无可避免的,自动化意味着映射和关联管理,代价是牺牲性能(早期,这是所有不喜欢ORM人的共同点)。现在的各种ORM框架都在尝试使用各种方法来减轻这块(LazyLoad,Cache),效果还是很显著的。
二、SQLAlchemy框架与数据库API
在Python中,最有名的ORM框架是SQLAlchemy。用户包括openstack\Dropbox等知名公司或应用,主要用户列表http://www.sqlalchemy.org/organizations.html#openstack
需要自己把数据库中的表映射成类,然后才能通过对象的方式去调用。SQLAlchemy不止可以支持MYSQL,还可以支持Oracle等。
Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作:
MySQL-Python mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname> pymysql mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>] MySQL-Connector mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname> cx_Oracle oracle+cx_oracle://user:[email protected]:port/dbname[?key=value&key=value...] 更多详见:http://docs.sqlalchemy.org/en/latest/dialects/index.html
安装SQLAlchemy:
pip install SQLAlchemy
三、连接数据库并查询
1 from sqlalchemy import create_engine
2
3 #连接数据库,生成engine对象;最大连接数为5个
4 engine = create_engine("mysql+pymysql://root:[email protected]:3306/zcl", max_overflow=5)
5 print(engine) #Engine(mysql+pymysql://root:***@127.0.0.1:3306/zcl)
6 result = engine.execute(‘select * from students‘) #不用commit(),会自动commit
7 print(result.fetchall())
输出:
Engine(mysql+pymysql://root:***@127.0.0.1:3306/zcl) [(1, ‘zcl‘, ‘man‘, 22, ‘15622341234‘, None), (2, ‘alex‘, ‘man‘, 30, ‘15622341235‘, None), (5, ‘Jack‘, ‘man‘, 25, ‘1351234‘, ‘CN‘), (6, ‘Mary‘, ‘female‘, 18, ‘1341234‘, ‘USA‘), (10, ‘Jack‘, ‘man‘, 25, ‘1351234‘, ‘CN‘), (11, ‘Jack2‘, ‘man‘, 25, ‘1351234‘, ‘CN‘), (12, ‘Mary‘, ‘female‘, 18, ‘1341234‘, ‘USA‘), (13, ‘cjy‘, ‘man‘, 18, ‘1562234‘, ‘USA‘), (14, ‘cjy2‘, ‘man‘, 18, ‘1562235‘, ‘USA‘), (15, ‘cjy3‘, ‘man‘, 18, ‘1562235‘, ‘USA‘), (16, ‘cjy4‘, ‘man‘, 18, ‘1562235‘, ‘USA‘), (17, ‘cjy5‘, ‘man‘, 18, ‘1562235‘, ‘USA‘)]
四、创建表
创建user与color表: 创建表时需要与MetaData的实例绑定。
1 from sqlalchemy import create_engine, 2 Table, Column, Integer, String, MetaData, ForeignKey
3
4 metadata = MetaData() #相当于实例一个父类
5
6 user = Table(‘user‘, metadata, #相当于让Table继承metadata类
7 Column(‘id‘, Integer, primary_key=True),
8 Column(‘name‘, String(20)),
9 )
10
11 color = Table(‘color‘, metadata, #表名color
12 Column(‘id‘, Integer, primary_key=True),
13 Column(‘name‘, String(20)),
14 )
15 engine = create_engine("mysql+pymysql://root:[email protected]:3306/zcl", max_overflow=5)
16
17 metadata.create_all(engine) #table已经与metadate绑定
查看创建的表:
五、增删改查
先来了解下原生sql语句的增删改查:
1 from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey,select
2
3 metadata = MetaData()
4
5 user = Table(‘user‘, metadata,
6 Column(‘id‘, Integer, primary_key=True),
7 Column(‘name‘, String(20)),
8 )
9
10 color = Table(‘color‘, metadata,
11 Column(‘id‘, Integer, primary_key=True),
12 Column(‘name‘, String(20)),
13 )
14 engine = create_engine("mysql+pymysql://root:[email protected]:3306/zcl", max_overflow=5)
15
16 conn = engine.connect() #创建游标,当前实例所处状态
17
18 # 创建SQL语句,INSERT INTO "user" (id, name) VALUES (:id, :name)
19 #id号可省略,默认是自增的
20 # conn.execute(user.insert(), {‘id‘: 1, ‘name‘: ‘zcl‘})
21 # conn.close()
22
23 # sql = user.insert().values(name=‘wu‘) #插入
24 # conn.execute(sql)
25 # conn.close()
26
27 #删除id号大于1的行,也可以where(user.c.name=="zcl")
28 # sql = user.delete().where(user.c.id > 1)
29 # conn.execute(sql)
30 # conn.close()
31
32 # 将name=="wuu"更改为"name=="ed"
33 # sql = user.update().where(user.c.name == ‘wuu‘).values(name=‘ed‘)
34 # conn.execute(sql)
35 # conn.close()
36
37 #查询 下面不能写 sql = user.select... 会曝错
38 #sql = select([user, ]) #[(1, ‘zcl‘), (9, ‘ed‘), (10, ‘ed‘)]
39 # sql = select([user.c.id, ]) #[(1,), (9,), (10,)]
40 sql = select([user.c.name, color.c.name]).where(user.c.id==color.c.id)
41 # sql = select([user.c.name]).order_by(user.c.name)
42 # sql = user.select([user]).group_by(user.c.name)
43
44 result = conn.execute(sql)
45 print(result.fetchall())
46 conn.close()
通过SQLAlchemy的增删改查(重要):
1 from sqlalchemy import create_engine
2 from sqlalchemy.ext.declarative import declarative_base
3 from sqlalchemy import Column,Integer,String
4 from sqlalchemy.orm import sessionmaker
5
6 Base = declarative_base() #生成一个SqlORM基类(已经封装metadata)
7 #echo=True可以查看创建表的过程
8 engine = create_engine("mysql+pymysql://root:[email protected]:3306/zcl", echo=True)
9
10 class Host(Base):
11 __tablename__ = ‘hosts‘ #表名为host
12 id = Column(Integer, primary_key=True, autoincrement=True)
13 hostname = Column(String(64), unique=True, nullable=False)
14 ip_addr = Column(String(128), unique=True, nullable=False)
15 port = Column(Integer, default=22)
16
17
18 Base.metadata.create_all(engine) #创建所有表结构
19
20 if __name__ == ‘__main__‘:
21 #创建与数据库的会话sessionclass,注意,这里返回给session的是个class类,不是实例
22 SessionCls=sessionmaker(bind=engine)
23 session=SessionCls() #连接的实例
24 #准备插入数据
25 h1 = Host(hostname=‘localhost‘, ip_addr=‘127.0.0.1‘) #实例化(未创建)
26 h2 = Host(hostname=‘ubuntu‘, ip_addr=‘192.168.2.243‘, port=20000)
27
28 #session.add(h1) #也可以用下面的批量处理
29 #session.add_all([h1,h2])
30 #h2.hostname=‘ubuntu_test‘ #只要没提交,此时修改也没问题
31
32 #查询数据,返回一个对象
33 obj = session.query(Host).filter(Host.hostname=="localhost").first()
34 print("-->",obj)
35 #[<__main__.Hostobjectat0x00000000048DC0B8>]如果上面为.all()
36 #<__main__.Hostobjectat0x000000000493C208>如果上面为.first()
37
38 #如果用.all(),会曝错AttributeError:‘list‘objecthasnoattribute‘hostname‘
39 #obj.hostname = "localhost_1" #将主机名修改为localhost_1
40
41 session.delete(obj) #删除行
42
43 session.commit()#提交
操作结果截图:
转发注明出处: http://www.cnblogs.com/0zcl/p/6504696.html
先睡觉,等下写sqlalchemy下篇~