參考原文:https://www.cnblogs.com/blueberry-mint/p/14277882.html
1 簡介
SQLAlchemy是用Python編程語言開發的一個開源項目。它提供了SQL工具包和ORM(對象關系映射)工具,使用MIT許可證發行。
SQLAlchemy最初在2006年2月發行,發行后便很快的成為Python社區中最廣泛使用的ORM工具之一,絲毫不亞於Django自帶的ORM框架。
SQLAlchemy采用簡單的Python語言,提供高效和高性能的數據庫訪問,實現了完整的企業級持久模型。它的理念是,SQL數據庫的量級和性能比對象集合重要,而對象集合的抽象又重要於表和行。
2 基本用法
2.1 安裝
安裝sqlachemy
pip3 install sqlalchemy pip3 install pymysql
本文使用MySQL作為數據庫,使用pymysql作為驅動,因此需要安裝pymysql
2.2 連接數據庫
配置信息
在連接數據庫前,需要使用到一些配置信息,然后把它們組合成滿足以下條件的字符串:
dialect+driver://username:password@host:port/database
- dialect:數據庫,如:sqlite、mysql、oracle等
- driver:數據庫驅動,用於連接數據庫的,本文使用pymysql
- username:用戶名
- password:密碼
- host:IP地址
- port:端口
- database:數據庫
建議將這些配置信息放到一個配置文件中,如config.py然后倒入配置文件
config.py
HOST = '192.168.1.180'
PORT = 3306
USERNAME = 'root'
PASSWORD = 'password'
DB = 'myclass'
# f代表可以使用{}引用變量
DB_URI = f'mysql+pymysql://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/{DB}'
# 以下語句和上面語句作用一致
# DB_URI = 'mysql+pymysql://%s:%s@%s:%s/%s'%(USERNAME,PASSWORD,HOST,PORT,DB)
創建引擎並連接數據庫
注意:本次操作的數據庫名為myclass需要提前創建好
from sqlalchemy import create_engine
from config import DB_URI
engine = create_engine(DB_URI) # 創建引擎
conn = engine.connect() # 連接
result = conn.execute('SELECT 1') # 執行SQL
print(result.fetchone())
conn.close() # 關閉連接
這里執行是SQL語句可以參考 https://www.cnblogs.com/minseo/p/15291725.html 是一致的
創建ORM模型並映射到數據庫中
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from config import DB_URI
# print(DB_URI)
# mysql+pymysql://root:password@192.168.1.180:3306/myclass
# 創建引擎
engine = create_engine(DB_URI)
#sconn = engine.connect()
# 創建SQLORM基類,注意這里要加參數,參數為上一步創建的引擎
Base = declarative_base(engine)
# 構建session對象
session = sessionmaker(engine)()
# 創建student表
# 該表有4列分別為自增id name age sex
# 分別代表id 姓名 年齡 性別其中id age為整數 name和sex為字符串
class Student(Base):
__tablename__ = 'student' # 表名
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50))
age = Column(Integer)
sex = Column(String(10))
# 將模型映射到數據庫中
# 即如果數據庫中沒有student表則創建映射表student
Base.metadata.create_all()
執行上面代碼,將會在數據庫中生成對應的映射表student
可以登錄MySQL查看建表語句
mysql> show create table student; +---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +---------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | student | CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, `age` int(11) DEFAULT NULL, `sex` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8
注意:如果表結構有修改,例如增加一個字段address
address = Column(String(100))
再執行不會修改表,只有刪除表再執行才會重新創建表並且新增這個字段
即執行Base.metadata.create_all()是如果數據庫里面沒有表則創建表,如果有表則不進行操作
新增數據
在添加數據之前可以把以下代碼注釋,因為表已經創建好了,無需執行
Base.metadata.create_all()
創建好表以后,接下來我們要添加數據,代碼如下
# 新增數據 # 創建一個Student對象 student = Student(name='Tony',age=18,sex='male') # 添加到session session.add(student) # 提交到數據庫 session.commit()
添加數據以后查看
mysql> select * from student; +----+------+------+------+ | id | name | age | sex | +----+------+------+------+ | 1 | Tony | 18 | male | +----+------+------+------+
也可以批量添加數據
# 批量添加數據
# 使用add_all()方法傳遞的參數為list
# list對象為Student對象
session.add_all([
Student(name='Jane', age=16, sex='female'),
Student(name='Ben', age=20, sex='male')
])
session.commit()
查詢數據庫現在有3條數據了
mysql> select * from student; +----+------+------+--------+ | id | name | age | sex | +----+------+------+--------+ | 1 | Tony | 18 | male | | 2 | Jane | 16 | female | | 3 | Ben | 20 | male |
查詢數據
sqlalchemy提供了query()方法來查詢數據
獲取所有數據
# 查詢數據
# 獲取所有數據
item_list = session.query(Student).all()
# 獲取的是Student對象
print(item_list)
# [<__main__.Student object at 0x000002748DEC2BE0>, <__main__.Student object at 0x000002748DEC2C50>, <__main__.Student object at 0x000002748DEC2CC0>]
# 遍歷通過對象的屬性打印對應的數據
for item in item_list:
print(item.name, item.age)
# Tony 18
# Jane 16
# Ben 20
查詢得到的item_list是一個包含多個Student對象的列表
指定列查詢
# 指定列查詢
# 指定查詢name列
# 類似於執行sql語句select name from student;
item_list = session.query(Student.name).all()
# 查詢的數據組成一個list,數據為元組為查詢的結果
# 可以指定多個列以,分隔,獲取的結果的元組也以,分隔
print(item_list)
# [('Tony',), ('Jane',), ('Ben',)]
獲取返回數據的第一行
# 獲取返回數據的第一行
item = session.query(Student.name).first()
print(item)
# ('Tony',)
使用filter()方法過濾
# 使用filter方法過濾
item_list = session.query(Student.name).filter(Student.age >= 18).all()
print(item_list)
# [('Tony',), ('Ben',)]
使用order_by()進行排序
# 使用order_by()進行排序
# 使用列name和age查詢並且使用age進行倒序
item_list = session.query(Student.name,Student.age).order_by(Student.age.desc()).all()
print(item_list)
# [('Ben', 20), ('Tony', 18), ('Jane', 16)]
多條件查詢
# 多條件查詢條件以,分隔默認為and item_list = session.query(Student.name, Student.age, Student.sex).filter(Student.age >= 10, Student.sex == 'female').all() print(item_list)
以上查詢語句類似於sql語句
mysql> select name,age,sex from student where age<=16 and sex='female'; +------+------+--------+ | name | age | sex | +------+------+--------+ | Jane | 16 | female | +------+------+--------+ 1 row in set (0.00 sec)
使用or_連接多個條件
# 以or條件查詢
# 需要導入or_
from sqlalchemy import or_
item_list = session.query(Student.name,Student.age,Student.sex).filter(or_(Student.age >=20,Student.sex=='female')).all()
print(item_list)
# [('Jane', 16, 'female'), ('Ben', 20, 'male')]
equal/like/in
下面示例查詢等於,不等於,like是模糊查詢,in是出現是否包含傳遞參數列表類元素
# equal/like/in
# 等於 查詢age等於18的對象
item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age==18).all()
print(item_list)
# [('Tony', 18, 'male')]
# 不等於
item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age != 18).all()
print(item_list)
# [('Jane', 16, 'female'), ('Ben', 20, 'male')]
# like
# 查詢名字有有To字符的對象
item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.name.like('%To%')).all()
print(item_list)
# [('Tony', 18, 'male')]
# in
# 查詢age為16或者20的對象,不是16到20的區間
# 注意這里in后面有一個_符號
item_list = session.query(Student.name,Student.age,Student.sex).filter(Student.age.in_([16,20])).all()
print(item_list)
# [('Jane', 16, 'female'), ('Ben', 20, 'male')]
count計算個數
# count計算個數 count = session.query(Student).count() print(count) # 3
切片
# 切片,和Python切片方法一樣
item_list = session.query(Student.name).all()[:2]
print(item_list)
# [('Tony',), ('Jane',)]
修改數據
修改數據可以使用update()方法,update完成后記得執行session.commit()
# 修改數據
# 把Tony的age修改為22
# 先查詢對象,filter設置過濾條件,update修改數據
session.query(Student).filter(Student.name=='Tony').update({'age':22})
session.commit()
刪除數據
刪除數據使用delete()方法,同樣也需要執行session.commit()提交事務
# 刪除數據 session.query(Student).filter(Student.name=='Tony').delete() session.commit()
注意:增刪改查除了查詢不設計修改操作,其他增刪改都需要使用commit()方法提交事務
