上一篇简单的介绍了MySQL的原生命令,以及如何使用pymysql模块在Python里面使用。这一节简单的介绍一下sqlAlchemy和他的ORM框架。ORM框架允许开发人员通过类的方法来操作数据库,而无需在使用原生的SQL语句。
例1. 单表的操作
#导入模块
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
#创建一个engine,基本格式是数据库类型名字+驱动://用户名:密码@主机:端口/数据库
engine = create_engine("mysql+pymysql://yli:yli@sydnagios:3306/mydb", max_overflow=5)
#声明一个基类
Base = declarative_base()
# 定义一个类,继承基类
class Test(Base):
#表名
__tablename__ = 'test'
#列名nid,整型,主键,自增
nid = Column(Integer, primary_key=True,autoincrement=True)
#列名name,字符串型
name = Column(String(32))
#通过类创建表,本质其实是在通过pymysql执行sql语句
def init_db():
Base.metadata.create_all(engine)
#删除表
def drop_db():
Base.metadata.drop_all(engine)
init_db()
#绑定数据库
Session = sessionmaker(bind=engine)
session = Session()
#添加一条数据并提交
session.add(Test(name='apple'))
session.commit()
#查询Test表
ret=session.query(Test)
#自动转换成sql语句
print(ret)
#sql语句的结果,all()返回所有的对象的结果,以列表结果显示,first()只显示第一个结果
print(ret.first())
#显示这个对象的属性值
print(ret.first().nid,ret.first().name)
--------------
SELECT test.nid AS test_nid, test.name AS test_name
FROM test
<__main__.Test object at 0x0000021D709F9438>
1 apple
修改
session.query(Test).filter(Test.nid==1).update({"name":"pear"})
session.commit()
删除
session.query(Test).filter(Test.nid==1).delete()
session.commit()
例2. 1对多联表的查询
group表和user表之间通过group_id形成外键约束
#导入模块
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
engine = create_engine("mysql+pymysql://yli:yli@sydnagios:3306/mydb", max_overflow=5)
Base = declarative_base()
# 一对多
class Group(Base):
#表名
__tablename__ = 'group'
#列名
nid = Column(Integer, primary_key=True,autoincrement=True)
caption = Column(String(32))
class User(Base):
#表名
__tablename__ = 'user'
#列名
nid = Column(Integer, primary_key=True,autoincrement=True)
username = Column(String(32))
#外键约束
group_id = Column(Integer, ForeignKey('group.nid'))
#显示这个类的对象的时候不再显示内存地址,而是执行这个方法
def __repr__(self):
temp = "%s - %s: %s" %(self.nid, self.username, self.group_id)
return temp
def init_db():
Base.metadata.create_all(engine)
def drop_db():
Base.metadata.drop_all(engine)
init_db()
Session = sessionmaker(bind=engine)
session = Session()
#添加
session.add(Group(caption='dba'))
session.add(Group(caption='ddd'))
session.commit()
#批量添加
session.add_all([
User(username='alex1',group_id=1),
User(username='alex2',group_id=2)
])
session.commit()
# 只是获取用户表的内容,通过filter进行过滤
ret = session.query(User).filter(User.username == 'alex1')
#显示对应的sql语句
print(ret)
#显示对象,这里自动调用_repr_方法
print(ret.all())
#不过滤
ret = session.query(User).all()
#获取列表里面的第一个对象
obj = ret[0]
print(ret)
print(obj)
#获取这个对象属性值
print(obj.nid)
print(obj.username)
print(obj.group_id)
--------
SELECT user.nid AS user_nid, user.username AS user_username, user.group_id AS user_group_id
FROM user
WHERE user.username = %(username_1)s
[1 - alex1: 1, 3 - alex1: 1]
[1 - alex1: 1, 2 - alex2: 2, 3 - alex1: 1, 4 - alex2: 2]
1 - alex1: 1
1
alex1
1
在上面的基础上,如果我们希望执行联表查询,可以有两种方式。
第一种,通过join实现。修改一下上面的例子
例如
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
engine = create_engine("mysql+pymysql://yli:yli@sydnagios:3306/mydb", max_overflow=5)
Base = declarative_base()
# 一对多
class Group(Base):
__tablename__ = 'group'
nid = Column(Integer, primary_key=True,autoincrement=True)
caption = Column(String(32))
class User(Base):
__tablename__ = 'user'
nid = Column(Integer, primary_key=True,autoincrement=True)
username = Column(String(32))
group_id = Column(Integer, ForeignKey('group.nid'))
def __repr__(self):
temp = "%s - %s: %s" %(self.nid, self.username, self.group_id)
return temp
def init_db():
Base.metadata.create_all(engine)
def drop_db():
Base.metadata.drop_all(engine)
# init_db()
Session = sessionmaker(bind=engine)
session = Session()
#查询user表的username字段的所有信息
ret = session.query(User.username).all()
print(ret)
#left join的效果
sql = session.query(User,Group).join(Group, isouter=True)
print(sql)
ret = session.query(User,Group).join(Group, isouter=True).all()
print(ret)
-----------
"C:\Program Files\Python3\python.exe" C:/Users/yli/Downloads/a39dab3773523eacb8c8568b446bbcec580842/day13/s1.py
[('alex1',), ('alex2',), ('alex1',), ('alex2',), ('alex1',), ('alex2',), ('alex1',), ('alex2',)]
SELECT user.nid AS user_nid, user.username AS user_username, user.group_id AS user_group_id, `group`.nid AS group_nid, `group`.caption AS group_caption
FROM user LEFT OUTER JOIN `group` ON `group`.nid = user.group_id
[(1 - alex1: 1, <__main__.Group object at 0x0000027295723630>), (2 - alex2: 2, <__main__.Group object at 0x0000027295723710>), (3 - alex1: 1, <__main__.Group object at 0x0000027295723630>), (4 - alex2: 2, <__main__.Group object at 0x0000027295723710>), (5 - alex1: 1, <__main__.Group object at 0x0000027295723630>), (6 - alex2: 2, <__main__.Group object at 0x0000027295723710>), (7 - alex1: 1, <__main__.Group object at 0x0000027295723630>), (8 - alex2: 2, <__main__.Group object at 0x0000027295723710>)]
第二种,通过relation实现
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
from sqlalchemy.orm import sessionmaker, relationship
engine = create_engine("mysql+pymysql://yli:yli@sydnagios:3306/mydb", max_overflow=5)
Base = declarative_base()
# 一对多
class Group(Base):
__tablename__ = 'group'
nid = Column(Integer, primary_key=True,autoincrement=True)
caption = Column(String(32))
class User(Base):
__tablename__ = 'user'
nid = Column(Integer, primary_key=True,autoincrement=True)
username = Column(String(32))
group_id = Column(Integer, ForeignKey('group.nid'))
#指定relationship,通过User找Group正向关系是‘Group’,通过Group找user是u,这个是个虚拟的关系,不影响表的实际结构
group=relationship('Group',backref='u')
def __repr__(self):
temp = "%s - %s: %s" %(self.nid, self.username, self.group_id)
return temp
def init_db():
Base.metadata.create_all(engine)
def drop_db():
Base.metadata.drop_all(engine)
# init_db()
Session = sessionmaker(bind=engine)
session = Session()
#正向的查询
ret=session.query(User).all()
print(ret)
for obj in ret:
print(obj.username,obj.group.caption)
#逆向的查询
ret=session.query(Group).filter(Group.caption=='dba').first()
print(ret.caption,ret.u)
for j in ret.u:
print(j.username)
--------------
[1 - alex1: 1, 2 - alex2: 2, 3 - alex1: 1, 4 - alex2: 2, 5 - alex1: 1, 6 - alex2: 2, 7 - alex1: 1, 8 - alex2: 2]
alex1 dba
alex2 ddd
alex1 dba
alex2 ddd
alex1 dba
alex2 ddd
alex1 dba
alex2 ddd
#逆向
dba [1 - alex1: 1, 3 - alex1: 1, 5 - alex1: 1, 7 - alex1: 1]
alex1
alex1
alex1
alex1
下一篇继续学习多表之间的联合查询