參考原文: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()方法提交事務