SQLAlchemy簡介
SQLAlchemy是Python SQL工具包和對象關系映射器,是python中最著名的ORM(Object Relationship Mapping)框架,它簡化了應用程序開發人員在原生SQL上的操作,使開發人員將主要精力都放在程序邏輯上,從而提高開發效率。它提供了一整套著名的企業級持久性模式,設計用於高效和高性能的數據庫訪問。
使用ORM操作數據庫:
優勢 :代碼易讀,隱藏底層原生SQL語句,提高了開發效率。
劣勢 :執行效率低 ,將方法轉換為原生SQL后 原生SQL不一定是最優的。
環境:
centos 7 x64 python 3.6 SQLAlchemy 1.3.16 pymysql 0.9.3 mariadb 5.5.64
關於如何安裝上述環境,這里不做演示,相信大家能搜到這篇文章,想必這種小問題不在話下。
連接數據庫
sqlalchemy.create_engine(*args, **kwargs):簡介
sqlalchemy支持的數據庫:
- PostgreSQL
- MySQL
- Oracle
- SQL Server
- SQLite
sqlalchemy.create_engine(*args, **kwargs):創建數據庫實例。
常用參數:
Engine:用URL的方式填寫連接數據庫所需的數據。如下格式:
db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@127.0.0.1:3306/數據庫名?charset=utf8')
case_sensitive=True:如果為False,在查詢獲取列名時將不區分大小寫。
connect_args:值是一個字典,用於設置數據庫連接參數,連接數據庫時可以傳遞自定義參數。如下將連接信息存放到字典中。
# 將連接信息放到connect_args字典中 db = create_engine('mysql+pymysql://', connect_args={'user': '用戶名', 'password': '密碼', 'host': '數據庫地址', 'port': 3306, 'database': '數據庫', 'charset': 'utf8'})
creator:值是函數名,該函數返回數據庫連接對象。如下:
from sqlalchemy import create_engine import pymysql # 使用pymysql獲取連接對象 def connect_sql(): connect = pymysql.connect( host='數據庫地址', user='用戶名', password='密碼', db='數據庫', charset='utf8', ) return connect # 獲取數據庫實例 db = create_engine('mysql+pymysql://',creator=connect_sql)
echo=False:如果為True會將執行的SQL語句及引擎執行的過程寫到默認的日志當中,默認日志使用sys.stdout作為輸出。echo的值除了True|False還可以設置為'debug'等字符串的形式來調整日志等級。如下:
# 設置日志等級 db = create_engine('mysql+pymysql://', connect_args={'user': '用戶名', 'password': '密碼', 'host': '數據庫地址', 'port': 3306, 'database': '數據庫', 'charset': 'utf8'},echo='debug')
echo_pool=False:如果為True將會記錄連接池的遷入與遷出,默認日志使用sys.stdout作為輸出,echo_pool的值除了True|False還可以設置為'debug'等字符串的形式來調整日志等級。
encoding:SQLAlchemy對從數據庫中獲取的數據編碼|解碼方式,默認是utf-8。
isolation_level:數據庫事物隔離,值是:"SERIALIZABLE"、 "REPEATABLE_READ"、 "READ_COMMITTED"、"READ_UNCOMMITTED" 、"AUTOCOMMIT".,具體以后端使用的數據庫為准。
logging_name:sqlalchemy.engine記錄器中生成的日志記錄的“name”字段,默認為對象id的十六進制字符串。
max_identifier_length:值是一個整數,用於設置SQL標識符(如表名、列名或標簽名)的最大字符數。
max_overflow=10:允許連接池內“溢出”的連接數,即在池大小設置之外打開的連接數。這只用於QueuePool。
module=None :對Python模塊對象(模塊本身,而不是其字符串名稱)的引用,如mysql使用pymysql驅動,此參數將繞過導入,而使用給定的模塊,直接操作數據庫。可用於測試DBAPI以及將“模擬”DBAPI實現注入引擎。
pool=None:如果值不是None,則是pool的實例或者QueuePool 的實例,此時將繞過URL參數中的連接參數,使用給定的pool或QueuePool作為engine的基礎連接池。所謂pool池其實就是指數據庫連接實例。
pool_size=5:連接池中保持打開狀態的連接數,池大小設置為0表示沒有限制,禁用池,將poolclass設置為NullPool。
poolclass=None:用戶自定義連接池。
pool_recycle=-1 :在給定的秒數之后回收連接。默認為-1表示沒有超時。例如,設置為3600意味着連接將在一小時內連接上如果沒有任何活動將被回收。注意,如果在八小時內未在連接上檢測到任何活動,MySQL將自動斷開連接(盡管這可以通過MySQLDB連接本身和服務器配置進行配置)。
pool_reset_on_return='rollback':設置底層池對象的Pool.reset_on_return參數,該參數可以設置為值“rollback”、“commit”或“None”。
pool_timeout=30:獲取連接池的超時時間單位是秒。
pool_use_lifo=False:從隊列池檢索連接時使用后進先出,而不是先進先出。使用后進先出,服務器端超時方案可以減少在非高峰使用期間使用的連接數。在計划服務器端超時時,請確保使用了回收或預ping策略來優雅地處理過時的連接。
plugins:要加載的插件名稱的字符串列表。
SQLAlchemy簡單示例
1、准備數據庫sql_test
MariaDB [(none)]> create database sql_test;
2、連接sql_test數據庫,獲取數據庫實例
from sqlalchemy import create_engine import pymysql # 第一種獲取數據庫實例的方法 def connect_sql(): # 使用pymysql獲取連接對象 connect = pymysql.connect( host='數據庫地址', user='用戶名', password='密碼', db='數據庫', charset='utf8', ) return connect # 獲取數據庫實例 db = create_engine('mysql+pymysql://',creator=connect_sql) # 第二種獲取數據庫實例的方法 db = create_engine('mysql+pymysql://', connect_args={'user': '用戶名', 'password': '密碼', 'host': '數據庫地址', 'port': 3306, 'database': '數據庫', 'charset': 'utf8'}) # 第三種獲取數據庫實例的方法 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8')
3、在數據庫中創建表
在創建表時由於是使用的ORM,所以需要將創建好的類與SQLAlchemy底層建表的類進行映射,類似於Django中類要繼承model類一樣。
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine # 獲取數據庫實例 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8') # 建立映射關系 Base = declarative_base() class User(Base): __tablename__ = 'users' # 設置表明 id = Column(Integer,primary_key=True) name = Column(String(32)) age = Column(Integer) # 創建表 Base.metadata.create_all(db)
運行上面的代碼后會在數據庫sql_test中創建一個名為users的表。
創建多個表只需要創建多個類即可,如下:
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine # 獲取數據庫實例 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8') # 建立映射關系 Base = declarative_base() class User(Base): __tablename__ = 'users' # 設置表明 id = Column(Integer,primary_key=True) name = Column(String(32)) age = Column(Integer) class Table_1(Base): __tablename__ = 'table_1' # 設置表明 id = Column(Integer,primary_key=True) name = Column(String(32)) age = Column(Integer) class Table_2(Base): __tablename__ = 'table_2' # 設置表明 id = Column(Integer,primary_key=True) name = Column(String(32)) age = Column(Integer) # 創建表 Base.metadata.create_all(db)
最終你會看到如下:
4、向表中添加數據。
以上面創建好的users表為示例:
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 獲取數據庫實例 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8') # 建立映射關系 Base = declarative_base() class User(Base): __tablename__ = 'users' # 設置表明 id = Column(Integer,primary_key=True) name = Column(String(32)) age = Column(Integer) # 向表中添加記錄 obj = User(name='小明',age=12) # 創建會話 obj_session = sessionmaker(db) # 打開會話 db_session = obj_session() # 向表中添加數據,此時數據保存在內存中 db_session.add(obj) # 提交數據,將數據保存到數據庫中 db_session.commit() # 關閉會話 db_session.close()
如果一切順利你會看到:
4.1向表中添加多條數據。
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 獲取數據庫實例 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8') # 建立映射關系 Base = declarative_base() class User(Base): __tablename__ = 'users' # 設置表明 id = Column(Integer, primary_key=True) name = Column(String(32)) age = Column(Integer) # 插入多條記錄 obj = [User(name='小麗', age=12), User(name='李紅', age=14), User(name='小剛', age=10)] # 創建會話 obj_session = sessionmaker(db) # 打開會話 db_session = obj_session() # 向表中添加數據,此時數據保存在內存中 db_session.add_all(obj) # 提交數據,將數據保存到數據庫中 db_session.commit() # 關閉會話 db_session.close()
如果成功會看到如下:
5、查詢表中數據
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 獲取數據庫實例 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8') # 建立映射關系 Base = declarative_base() class User(Base): __tablename__ = 'users' # 設置表明 id = Column(Integer, primary_key=True) name = Column(String(32)) age = Column(Integer) # 創建會話 obj_session = sessionmaker(db) # 打開會話 db_session = obj_session() # 查詢表中所有數據 all_list = db_session.query(User).all() for obj in all_list: print(obj.id,obj.name,obj.age) # 關閉會話 db_session.close()
如果表中有數據,你會看到如下:
6、使用filter過濾查詢條件
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 獲取數據庫實例 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8') # 建立映射關系 Base = declarative_base() class User(Base): __tablename__ = 'users' # 設置表明 id = Column(Integer, primary_key=True) name = Column(String(32)) age = Column(Integer) # 創建會話 obj_session = sessionmaker(db) # 打開會話 db_session = obj_session() # 使用filter過濾查詢條件 all_list = db_session.query(User).filter(User.name=='小明') for obj in all_list: print(obj.id,obj.name,obj.age) # 查看SQLAlchemy底層執行的sql語句 print(f'執行的sql語句:{all_list}') # 關閉會話 db_session.close()
打印結果如下:
7、 修改數據
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 獲取數據庫實例 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8') # 建立映射關系 Base = declarative_base() class User(Base): __tablename__ = 'users' # 設置表明 id = Column(Integer, primary_key=True) name = Column(String(32)) age = Column(Integer) # 創建會話 obj_session = sessionmaker(db) # 打開會話 db_session = obj_session() # 將小明的名字修改為娃哈哈 all_list = db_session.query(User).filter(User.name=='小明').update({'name':'娃哈哈'}) # 提交數據,將數據保存到數據庫中 db_session.commit() # 查看更改后的表 all_data = db_session.query(User).all() for obj in all_data: print(obj.id,obj.name,obj.age) # 關閉會話 db_session.close()
執行完成后你會看到如下:
8、刪除數據
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker # 獲取數據庫實例 db = create_engine('mysql+pymysql://數據庫用戶:數據庫密碼@數據庫地址:3306/數據庫名?charset=utf8') # 建立映射關系 Base = declarative_base() class User(Base): __tablename__ = 'users' # 設置表明 id = Column(Integer, primary_key=True) name = Column(String(32)) age = Column(Integer) # 創建會話 obj_session = sessionmaker(db) # 打開會話 db_session = obj_session() # 刪除id是1的行 all_list = db_session.query(User).filter(User.id==1).delete() # 提交數據,將數據保存到數據庫中 db_session.commit() # 刪除后查看表中數據 all_data = db_session.query(User).all() for obj in all_data: print(obj.id,obj.name,obj.age) # 關閉會話 db_session.close()
執行完成后,打印結果如下:
好了關於SQLAlchemy的增、刪、改、查先簡單介紹這里,關於SQLAlchemy的一些高級操作待更新。。。。。