SQLAlchemy是Python語言的一款流行的ORM(Object Relational Mapper)框架,該框架創建在數據庫API之上,使用關係對象映射進行數據庫操做,即將對象轉換成SQL,而後使用數據API執行SQL並獲取執行結果。html
安裝SQLAlchemy也很簡單,直接使用pip安裝便可。python
pip install sqlalchemy
下面重點介紹SQLAlchemy的使用。mysql
import sqlalchemy sqlalchemy.__version__ # 1.1.9
當前sqlalchemy版本爲1.1.9程序員
from sqlalchemy import create_engine engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True)
engine://user:password@host:port/database
,其中engine爲mysql+pymysql,或者是mysql+mysqldb,或者是oracle+cx_oracle等等from sqlalchemy import create_engine from sqlalchemy import Column, String, Integer from sqlalchemy.ext.declarative import declarative_base engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True) Base = declarative_base() # 生成Model類的基類 class User1(Base): __tablename__ = 'user1' extend_existing = True # 定義三個列 id = Column(Integer, autoincrement=True, primary_key=True) name = Column(String(64), unique=True, nullable=False) age = Column(Integer) def __repr__(self): return 'User(id={}, name={}, age={})'.format(self.id, self,name, self.age) def __str__(self): return self.__repr__() Base.metadata.create_all(engine) # 建立全部表 Base.metadata.drop_all(engine) # 刪除全部表 # 定義類的實例方法1 u1 = User() # User類只接收一個位置參數self,和關鍵字參數**kwargs u1.name = 'aa' # 給User類的各個列賦值 u1.age=19 print(u1) # User(id=None, name=aa, age=19) # 定義類的實例方法2 u2 = User(name='bb', age='123') print(u2) # User(id=None, name=bb, age=123)
__init__
,會自動的接受咱們所定義的列對應的關鍵字參數SQLAlchemy真正處理數據庫的部分是Session。sql
若是已經建立好了一個Engine對象engine,那麼能夠用如下語句建立一個Sessionshell
from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine)
若是engine爲建立好,則能夠用如下語句建立數據庫
Session = sessionmaker()
當engine建立好以後,在配置Session便可session
Session.configure(bind=engine)
當須要和數據庫交互的時候,就須要實例化Sessionoracle
session = Session()
建立完成以後這個session並無立刻獲取數據庫鏈接。只有當這個session第一次操做數據庫的時候纔會從Engine維護的鏈接池中獲取一個鏈接,並持有這個鏈接一直到咱們提交了全部的改變或者關閉了這個session。app
user = User(name='haha', age='123') session.add(user) session.commit()
若是這個commit的過程當中發生異常,則後續全部的commit都沒法執行,所以DML都須要放在try...except中處理,以下
user = User(name='flowsnow', age=18) session.add(user) try: session.commit() except Exception as e: session.rollback() raise e
和insert相似,都是使用session.add方法,可是update操做的時候須要數據庫中存在帶操做的記錄。
user.age = 20 session.add(user) try: session.commit() except Exception as e: session.rollback() raise e
刪除以前必須確保數據庫中存在要刪除的記錄。
session.delete(user) # user必須已經存在 try: session.commit() except Exception as e: session.rollback() raise e
for u in session.query(User).filter(User.age < 20).order_by(User.age.desc())[1:3]: print(u)
此條語句經ORM轉換以後的SQL以下:
SELECT USER.id AS user_id, USER.NAME AS user_name, USER.age AS user_age FROM USER WHERE USER.age < % (age_1) s ORDER BY USER.age DESC LIMIT % (param_1) s, % (param_2) s
query函數的返回結果爲一個Query對象,Query對象是可迭代的,支持切片操做。
下面列舉常見的filter操做
相等
query.filter(User.name == 'suncle')
不相等
query.filter(User.name != 'suncle')
模糊匹配like:大小寫敏感
query.filter(User.name.like('%sun%'))
模糊匹配ilike:大小寫不敏感
query.filter(User.name.ilike('%sun%'))
IN
query.filter(User.name.in_(['suncle', 'abc', 'suncle'])) # 也支持Query對象 query.filter(User.name.in_( session.query(User.name).filter(User.name.like('%sun%')) ))
NOT IN
query.filter(~User.name.in_(['ed', 'wendy', 'jack']))
IS NULL
query.filter(User.name == None) # 上面的寫法不符合pep8規範,IDE會給出提示,能夠用下面的方法替代,pep8的寫法是is None query.filter(User.name.is_(None))
IS NOT NULL
query.filter(User.name != None) # 上面的寫法不符合pep8規範,IDE會給出提示,能夠用下面的方法替代,pep8的寫法是is not None query.filter(User.name.isnot(None))
AND
# 方法1:使用and_()方法 from sqlalchemy import and_ query.filter(and_(User.name == 'flowsnow', User.age == 18)) # 方法2:filter()支持多個關鍵字參數 query.filter(User.name == 'flowsnow', User.age == 18) # 方法3:屢次調用filter函數 query.filter(User.name == 'flowsnow').filter(User.age == 18)
OR
from sqlalchemy import or_ query.filter(or_(User.name == 'suncle', User.name == 'flowsnow'))
下面列舉SQL支持的常見的function
from sqlalchemy import func session.query(func.count(User.id)).first() # count session.query(func.max(User.age)).first() # max session.query(func.avg(User.age)).first() # avg
表和表之間會有外鍵關係,數據庫的外鍵關係在ORM中的使用方法以下:
from sqlalchemy import create_engine from sqlalchemy import Column, Integer, String from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy import ForeignKey from sqlalchemy.orm import relationship Base = declarative_base() # 生成Model類的基類 class Author(Base): # 做者類 __tablename__ = 'author' id = Column(Integer, primary_key=True, autoincrement=True) name = Column(String(64), unique=True, nullable=False) posts = relationship('Post') def __repr__(self): return 'Author<id={}, name={}>'.format(self.id, self.name) def __str__(self): return self.__repr__() class Post(Base): # 文章類 __tablename__ = 'post' id = Column(Integer, primary_key=True, autoincrement=True) title = Column(String(128), nullable=False, index=True) content = Column(String(8096), nullable=False) author_id = Column(Integer, ForeignKey('author.id'), nullable=False) author = relationship('Author') def __repr__(self): return 'Post<id={}, title={}>'.format(self.id, self.title) def __str__(self): return self.__repr__() engine = create_engine('mysql+pymysql://root:123456@192.168.110.13:3306/student', echo=True) Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) session = Session() # 新增一個做者 author = Author() author.name = 'flowsnow' session.add(author) session.commit() print(author) # Author<id=1, name=flowsnow> # 新增一篇文章 post = Post() post.title = 'first post' post.content = 'oihdoshfohro' post.author = author session.add(post) session.commit() print(author.posts) # [Post<id=1, title=first post>] # 再新增一篇文章 post = Post() post.title = 'second post' post.content = 'liabhgekegpaerg' post.author = author session.add(post) session.commit() print(author.posts) # [Post<id=1, title=first post>, Post<id=2, title=second post>]
數據庫維護數據之間的外鍵關係會消耗數據庫資源,影響性能,在大型的應用中通常不使用外鍵等數據庫高級特性,而是由應用框架來維護數據之間的約束。
參考
記得幫我點贊哦!
精心整理了計算機各個方向的從入門、進階、實戰的視頻課程和電子書,按照目錄合理分類,總能找到你須要的學習資料,還在等什麼?快去關注下載吧!!!
念念不忘,必有迴響,小夥伴們幫我點個贊吧,很是感謝。
我是職場亮哥,YY高級軟件工程師、四年工做經驗,拒絕鹹魚爭當龍頭的斜槓程序員。
聽我說,進步多,程序人生一把梭
若是有幸能幫到你,請幫我點個【贊】,給個關注,若是能順帶評論給個鼓勵,將不勝感激。
職場亮哥文章列表:更多文章
本人全部文章、回答都與版權保護平臺有合做,著做權歸職場亮哥全部,未經受權,轉載必究!