Flask學習之旅--還是數據庫(sqlacodegen + SQL Alchemy)


一、寫在前面

  其實之前已經寫過一篇關於 Flask 中使用數據庫的博客了,不過那一篇博客主要是記錄我在使用 Flask + MySQL8.0 時所遇到的一些問題(如果用的不是 MySQL8.0估計就沒有這么多問題了!)。然后這一篇可以算作一份學習筆記了,也是關於在 Flask 中進行數據庫操作的,感覺寫這種學習筆記還是比較有用的,可以再學習一遍也就能更好的掌握了。

  在使用 Flask 的時候,一般都會創建一個 model.py,然后在里面繼承和創建模型,再遷移到數據庫中,最后進行一些增刪改查等操作。但是如果數據庫表已經建立好了呢?有沒有辦法將這些數據庫表引入到 Flask 中呢?

 

二、sqlacodegen

1.sqlacodegen簡介

  sqlacodegen pypi:https://pypi.org/project/sqlacodegen/

  其中對 sqlacodegen 的介紹是:這是一個工具,它讀取現有數據庫的結構並生成相應的 SQLAlchemy 模型代碼,如果可能,使用聲明式樣式。

  sqlacodegen 的幾個主要特性為:

  1)支持 SQLAlchemy 0.8.x - 1.3.x。

  2)生成幾乎看起來像是手寫的聲明性代碼。

  3)生成符合 PEP 8 標准的代碼。

  4)准確地確定關系,包括多對多,一對一。

  5)自動檢測連接表繼承。

2.sqlacodegen安裝

  使用 pip 安裝即可:

pip install sqlacodegen

3.sqlacodegen用法

  下面是一個 sqlacodegen 用法示例:

sqlacodegen mysql+pymysql://root:qwer1234@127.0.0.1/mydb --tables users,roles,phone >models.py

   首先是一個 sqlacodegen 命令,后面接上連接數據庫的語句,然后可以使用 --tables 指定要導入的數據表,最后用 >models.py 輸出到 models.py 中,如果不指定輸出文件,會將 python 代碼直接打印出來。下面是生成的 models.py 中的代碼:

 1 # coding: utf-8
 2 from sqlalchemy import Column, ForeignKey, String
 3 from sqlalchemy.dialects.mysql import INTEGER
 4 from sqlalchemy.orm import relationship
 5 from sqlalchemy.ext.declarative import declarative_base
 6 
 7 Base = declarative_base()
 8 metadata = Base.metadata
 9 
10 
11 class Phone(Base):
12     __tablename__ = 'phone'
13 
14     phone = Column(String(11), primary_key=True)
15     phone_address = Column(String(40))
16 
17 
18 class Role(Base):
19     __tablename__ = 'roles'
20 
21     role_id = Column(INTEGER(11), primary_key=True)
22     role_name = Column(String(45))
23 
24 
25 class User(Base):
26     __tablename__ = 'users'
27 
28     user = Column(String(10), primary_key=True)
29     sex = Column(String(10))
30     email = Column(String(45))
31     phone = Column(String(11))
32     role_id = Column(ForeignKey('roles.role_id'), index=True)
33 
34     role = relationship('Role')

 

三、SQL Alchemy

1.SQL Alchemy簡介

  SQL Alchemy pypi:https://pypi.org/project/SQLAlchemy/

  SQL Alchemy 是 Python SQL 工具包和對象關系映射器,它為應用程序開發人員提供了SQL的全部功能和靈活性。

  在寫上篇博客的時候簡單介紹過 Flask-SQLAlchemy,當時說到它將對 SQL Alchemy 的支持添加到 Flask 應用程序中,因此我們通過簡單設置之后就能在 Flask 中隊數據庫進行操作了,可那是當我們在把定義好的模型映射到數據庫中時所用的。如果數據庫表已經建好了,還怎么用 Flask-SQLAlchemy 來操作呢?這時候就需要使用 SQL Alchemy 了!

2.SQL Alchemy安裝

  使用 pip 安裝即可:

pip install SQLAlchemy

3.SQL Alchemy架構

  

  1)Schema / Types 定義了類到表之間的映射框架(規則)。

  2)SQL Expression Language 封裝好的 SQL 語句。

  3)Engine 操作者。

  4)Connection Pooling 連接池。

  5)Dialect 根據用戶的配置,調用不同的數據庫 API(如:Mysql) 並執行對應的 SQL 語句。

4.SQL Alchemy用法

(1)連接數據庫

1 from sqlalchemy import create_engine
2 
3 
4 engine = create_engine("mysql+pymysql://root:qwer1234@127.0.0.1:3306/mydb")

  create_engine() 會返回一個引擎實例,它代表着數據庫的接口。這個引擎實例可以執行 SQL 語句,例如:

engine.execute("show tables")

(2)創建會話

   光有這個數據庫的引擎還不夠,還需要建立會話才行,這里要使用引擎來創建一個 Session 類的實例,代碼為:

 1 from sqlalchemy import create_engine
 2 from sqlalchemy.orm import sessionmaker
 3 
 4 
 5 # 創建引擎
 6 engine = create_engine("mysql+pymysql://root:qwer1234@127.0.0.1:3306/mydb")
 7 # 使用引擎創建Session
 8 DB_Session = sessionmaker(bind=engine)
 9 # 實例化
10 db_session = DB_Session()

(3)單表 CRUD

  插入數據:

1 # 插入
2 db_session.execute("insert into roles values(%d,%s)" % (1, "'admin'"))
3 db_session.execute("insert into users values(%s,%s,%s,%s,%d)" % ("'user1'", "'man'", "'user1@163.com'", "'12233445566'", 1))
4 db_session.commit()

  插入數據可以使用 SQL 語句來完成,在插入數據之后要使用 commit(),這一點不能忘記。

  查詢數據:

1 # 查詢
2 result = db_session.query(User).filter(User.user == "user1")
3 print(result.all())
4 usr = result.all()[0]
5 print(usr.email)
6 
7 # [<SQlAlchemy.models.User object at 0x0000028D33D7CDD8>]
8 # user1@163.com

  在查詢的時候需要使用 query()  和 filter(),返回的結果是一個列表,如果列表為空就表示數據庫中沒有該記錄。對於返回的這個結果,使用 all() 返回所有記錄,使用 one() 返回第一條記錄。

  更新數據:

1 # 更新
2 db_session.query(User).filter(User.user == "user1").update({User.email: 'user1user1@163.com'})
3 db_session.commit()
4 # 查詢
5 result = db_session.query(User).filter(User.user == "user1")
6 usr = result.one()
7 print(usr.email)
8 
9 # user1user1@163.com

  更新數據可以使用 update() 方法,不過要接在 filter() 之后,使用這種方法即使數據庫中沒有記錄也不會報錯。

  刪除數據:

1 # 刪除
2 db_session.query(User).filter(User.user == "user1").delete()
3 # 查詢
4 result = db_session.query(User).filter(User.user == "user1")
5 usr = result.one()
6 print(usr.email)
7 
8 # sqlalchemy.orm.exc.NoResultFound: No row was found for one()

  刪除數據的使用方法和更新數據類似,只不過是在 filter() 之后使用 delete() 方法。

(4)多表查詢

   假設要查詢 phone 為"12233445566"的用戶名稱和電話所在地址,就需要將 users 表和 phone 表聯合起來進行查詢,方法是使用多個 filter():

1 res = db_session.query(User, Phone).filter(User.phone == "12233445566").filter(Phone.phone == "12233445566")
2 u, p = res.one()
3 print(u.user, p.phone_address)
4 
5 # user1 A

  假設要查詢 user 為"user1"的用戶的角色信息,就需要將 users 表和 roles 表聯合起來進行查詢,因為有外鍵的關系,所以可以使用 join():

1 res = db_session.query(User).join(Role).filter(User.user == "user1")
2 u = res.one()
3 print(u.user, u.role.role_name)
4 
5 # user1 admin

 


免責聲明!

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



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