sqlalchemy的基本用法


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM