sqlalchemy的使用
orm模型
object relationship map 模型
对象关联映射模型,意思就是把数据库中的表的相关结构映射成代码中的关系
表名 —>类名
字段 —>类属性
记录 —>实例化对象
这种模型的优势在于在程序中进行查询非常方便,省去了写原生的sql语句
创建表与连接表
我们操作的程序是停留在程序层面,它本身是无法进行数据库的操作的,数据库存在自己的接口,以mysql为例,使用的是自己给出的接口,其他的pymsql库能够对这个接口进行连接,这里都还是比较底层的,能连接mysql数据库的不止是pymysql,cymysql也可以,这些直接对接数据库接口的库我们称为驱动
我们当然可以直接调用这些驱动写原生的sql语句就能够进行数据库的操作,但是这样并不方便,因此有人开发了基于驱动之上的封装,比如现在使用的sqlalchemy,作为一个强大的库不可能只能连接mysql,也不可能只能使用一种pymysql驱动,因此在使用的时候还是需要告诉程序我们需要使用什么样的引擎
引擎的作用在于进行对应的数据库和驱动的声明,进行配置好,之后扔给我们的库,这样就能通过引擎,使用驱动,连接数据库
工作中很多时候我们不是创建表,而是连接数据库查询表,sqlalchemy提供的只有创建表和删除表,并不能对表结构进行任何的修改操作,比如添加或者删除一个字段,这是不允许的.
那么如果库里面已经有对应的表,使用sqlalchemy进行创建则不会成功,但是也不会报错,其操作方式为:有就不操作,没有就创建
删除则不会,这个是真的删除
# orm模型 对象 关系 映射 模型 object relationship map model
# 类名就是表名
# 实例化的对象就是数据库里面的记录
# 类属性就是表的字段
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column # 创建字段用
from sqlalchemy import Integer, String, DECIMAL # 导入对应的字段类型
from sqlalchemy import create_engine # 配置引擎
# 使用基类模型进行创建新的类,这个新的类就有了与表对应的结构映射关系
Base = declarative_base()
# 生成自己的类,类名就是表名
class Author(Base):
# 设置库里面的表名
__tablename__ = 'author'
# 主键id必须写
id = Column(Integer, primary_key=True)
# 作者名
name = Column('name',String(255))
class Book(Base):
# 设置库里面的表名
__tablename__ = 'book'
# 主键
id = Column(Integer, primary_key=True)
# 书名
name = Column('name', String(255))
# 存储价格
price = Column('price', DECIMAL)
# 作者id
author_id =Column('author_id', Integer)
# 连接数据库并简历表格
def link_mysql():
# 配置引擎
engine = create_engine('mysql+cymysql://root:root@127.0.0.1:3306/test')
# 利用基类创建表
Base.metadata.create_all(engine)
if __name__ == '__main__':
link_mysql()
engine的配置就是申明需要进行连接的库和使用的驱动
数据的添加
给对应的表进行添加数据,添加数据的py文件进行单独的数据写入操作,因为需要这个类去实例化对象,所以这里就需要进行对应导入,这里把创建表的文件命名为create_tables
在sqlchemy中进行的数据的增删改查操作,这些操作都是基于一个对象上进行的,得到这个对象需要使用这个库提供的sessionmake元类创建新的Sessoin类
数据添加有两个,add()或者使用add_all()分别表示单条和多条,多条添加需要的是列表对象,列表里面放着session对象,这是批量添加,单个add()表示添加一条数据,参数里面放置session对象
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from create_tables import Author, Book
# 这种对数据库的操作还是需要进行引擎的配置
engine = create_engine('mysql+cymysql://root:root@127.0.0.1:3306/test')
# 使用session对象进行操作
Session = sessionmaker(bind=engine)
# 使用Session类尽心实例化
session = Session()
# 进行数据的添加 随便写,姓名年龄随便加
source_data_author = {
'吴军': [40, [['走进大学', 30], ['数学之美', 144]]],
'吴承恩': [45, [['西游记', 50]]],
'蒲松龄': [44, [['聊斋志异', 60]]],
'曹雪芹': [50, [['红楼梦', 50]]],
'爱因斯坦': [32, [['相对论', 100]]],
'费曼': [35, [['费曼讲义', 101]]],
'德布罗意': [27, [['物质波', 120]]],
}
session.add_all([Author(name=k, age=v[0]) for k, v in source_data_author.items()])
session.commit()
create_tables是前面的表格创建文件,这里导入文件中的两个表格,这里只是使用了Author表,每次修改操作后都需要进行提交
下面是进行Book表的添加
# 因为book表中与author表中存在外键关系 所以进行单独写
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from create_tables import Book, Author
engine = create_engine('mysql+cymysql://root:root@127.0.0.1:3306/test')
Session = sessionmaker(bind=engine)
session = Session()
# 准备添加的数据
source_data_author = {
'走进大学': [30, '吴军'],
'数学之美': [144, '吴军'],
'西游记': [50, '吴承恩'],
'聊斋志异': [60, '蒲松龄'],
'红楼梦': [50, '曹雪芹'],
'相对论': [100, '爱因斯坦'],
'费曼讲义': [101, '费曼'],
'物质波': [120, '德布罗意'],
}
# 从这里添加图书信息 那么author_id需要通过查询author并对应找出人的id号
# session.query(Author.id).filter(Author.name == v[1]).first()[0] 表示查询出作者的id
data = [Book(name=k, price=v[0], author_id=session.query(Author.id).filter(Author.name == v[1]).first()[0]) for k, v in source_data_author.items()]
# 写进数据库
session.add_all(data)
session.commit()
查询的话需要进行指导filter和query的使用
已经存在了两个表,现在开始查询
# 这里是对应的查询语句
from sqlalchemy import create_engine
from create_tables import Author, Book
from sqlalchemy.orm import sessionmaker
# 准备好engine配置
engine = create_engine('mysql+cymysql://root:root@127.0.0.1:3306/test')
# 创建Session类
Session = sessionmaker(engine)
session = Session()
# 查询一个作者名下有哪些书,很明显作者表和书籍表需要链表查询
# 通过查询出author对象后再在这个对象上利用外键的to_book进行查询到book表
# 这是因为改写了__repr__方法的缘故,所以才查出来就是name
print(session.query(Author).filter(Author.name == '吴军').first().to_book)
# 列表中的每个元素都是查询对象,直接.属性名就查出对应字段
print([i.name for i in session.query(Author).filter(Author.name == '吴军').first().to_book])
# 查询出书籍的售价信息
print([i.price for i in session.query(Author).filter(Author.name == '吴军').first().to_book])
# 查询均价
data = [i.price for i in session.query(Author).filter(Author.name == '吴军').first().to_book]
print(sum(data) / len(data))
# 现在反过来,给定一本书,查询属于哪个作者 to_author是自定义的relationship对象
print(session.query(Book).filter(Book.name == '数学之美').first().to_author.name)