flask插件系列之SQLAlchemy基礎使用


sqlalchemy是一個操作關系型數據庫的ORM工具。下面研究一下單獨使用和其在flask框架中的使用方法。

直接使用sqlalchemy操作數據庫

安裝sqlalchemy

pip install sqlalchemy

初始化及操作數據庫

# 導入:
from sqlalchemy import Column, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

# 創建對象的基類:
Base = declarative_base()
class User(Base):
    '''用戶信息表'''
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String(80), unique=True)
    email = Column(String(320), unique=True)
    password = Column(String(32), nullable=False)
user = User(username='ming', email='dddd', password='1234567')

# 初始化數據庫連接:
engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
# 創建DBSession類型:
DBSession = sessionmaker(bind=engine)
# 創建單個會話
session = DBSession()
session = db_session()
session.add(user)
session.commit()
session.close()

# 通過創建會話池連接
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
session = db_session()
session.add(user)
session.commit()
session.close()

# 也可以創建連接
con = engine.connect()
con.execute("一個表對象",name='ffff',email='dddd', password='1234567')
con.close()

在flask框架中集成使用

安裝

pip install Flask-SQLAlchemy
  • 如果需要操作mysql數據庫,還需要安裝pymysql;
pip install pymysql

配置文件

  • Flask-SQLAlchemy可以將關於SQLAlchemy的配置集成到flask的配置文件中去,在初始化app的時候一起加載。相關的配置鍵有:

SQLALCHEMY_DATABASE_URI

用於連接數據的數據庫。例如:
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://caiwp:mysql@192.168.1.23:3307/tms_mysql?charset=utf8'
其格式為:mysql://username:password@server/db?編碼
注意默認使用mysqldb連接數據庫,要使用pymysql就需要用mysql+pymysql的格式;

SQLALCHEMY_COMMIT_ON_TEARDOWN

設置是否在每次連接結束后自動提交數據庫中的變動。
example:
SQLALCHEMY_COMMIT_ON_TEARDOWN = True

SQLALCHEMY_BINDS

一個映射綁定 (bind) 鍵到 SQLAlchemy 連接 URIs 的字典。他可以用來連接多個數據庫。
example:
SQLALCHEMY_BINDS = {
    'users':        'mysqldb://localhost/users',
    'appmeta':      'sqlite:////path/to/appmeta.db'
}
# 上面除了默認的連接外,又連接了兩個數據庫,分別命名users,appmeta。在創建模型的時候可以為相應的操作定制化;
# 更多的詳細參考:http://www.pythondoc.com/flask-sqlalchemy/binds.html#binds

SQLALCHEMY_ECHO

如果設置成 True,SQLAlchemy 將會記錄所有發到標准輸出(stderr)的語句,這對調試很有幫助;默認為false;
如:
SQLALCHEMY_ECHO = True

SQLALCHEMY_RECORD_QUERIES

可以用於顯式地禁用或者啟用查詢記錄。查詢記錄 在調試或者測試模式下自動啟用。
一般我們不設置。

SQLALCHEMY_NATIVE_UNICODE

可以用於顯式地禁用支持原生的unicode。

SQLALCHEMY_POOL_SIZE

數據庫連接池的大小。默認是數據庫引擎的默認值 (通常是 5)。
如:
SQLALCHEMY_POOL_SIZE = 10

SQLALCHEMY_TRACK_MODIFICATIONS

如果設置成 True (默認情況),Flask-SQLAlchemy 將會追蹤對象的修改並且發送信號。這需要額外的內存,如果不必要的可以禁用它。
example:
SQLALCHEMY_TRACK_MODIFICATIONS = Flase

SQLALCHEMY_MAX_OVERFLOW

控制在連接池達到最大值后可以創建的連接數。當這些額外的連接使用后回收到連接池后將會被斷開和拋棄。保證連接池只有設置的大小;
如:
SQLALCHEMY_MAX_OVERFLOW = 5

SQLALCHEMY_POOL_TIMEOUT

指定數據庫連接池的超時時間。默認是 10。
example:
SQLALCHEMY_POOL_TIMEOUT = 10

SQLALCHEMY_POOL_RECYCLE

自動回收連接的秒數。這對MySQL是必須的,默認情況下MySQL會自動移除閑置8小時或者以上的連接,Flask-SQLAlchemy會自動地設置這個值為 2 小時。也就是說如果連接池中有連接2個小時被閑置,那么其會被斷開和拋棄;
手動設置:
SQLALCHEMY_POOL_RECYCLE = 1200

常用配置

SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://caiwp:mysql@192.168.1.23:3307/tms_mysql?charset=utf8'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True

# 下面兩項調試階段啟動,部署時關閉
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_ECHO = True

常用的字段、關系類型

  • 常用的字段
類型名	                  python類型	            說明
Integer	                    int	                 普通整數,一般是32位
SmallInteger	            int	                 取值范圍小的整數,一般是16位
BigInteger	                int或long	        不限制精度的整數
Float	                    float	             浮點數
Numeric	                    decimal.Decimal	     普通整數,一般是32位
String	                    str	                 變長字符串
Text	                            str	                 變長字符串,對較長或不限長度的字符串做了優化
Unicode	                    unicode	             變長Unicode字符串
UnicodeText	                unicode	             變長Unicode字符串,對較長或不限長度的字符串做了優化
Boolean	                    bool	             布爾值
Date	                    datetime.date	     時間
Time	                    datetime.datetime	 日期和時間
LargeBinary	                str	                 二進制文件
Enum                        enum                 枚舉類型   
  • 常用列選項
primary_key	        如果為True,代表表的主鍵
unique	            如果為True,代表這列不允許出現重復的值
index	            如果為True,為這列創建索引,提高查詢效率
nullable	        如果為True,允許有空值,如果為False,不允許有空值
default	            為這列定義默認值,如default=1
  • 常用的關系選項
backref	            在關系的另一模型中添加反向引用,用於找到父表
primary join	    明確指定兩個模型之間使用的聯結條件
uselist	            如果為False,不使用列表,而使用標量值
order_by	        指定關系中記錄的排序方式
secondary	        指定多對多中記錄的排序方式
secondary join	    在SQLAlchemy中無法自行決定時,指定多對多關系中的二級聯結條件

創建模型類

from flask.ext.sqlalchemy import SQLAlchemy
# 指定一個字段為外鍵,必須使用類
from sqlalchemy.schema import ForeignKey

# 創建一個db對象
db = SQLAlchemy()

class User(db.Model):
    
    __bind_key__ = 'xxx' # 可以指定為哪個數據庫定義表
    __tablename__ = 'users'  # 定義表的名字
    # 定義表中的列字段,接收所有相關的對字段的定義的信息
    id = db.Column(db.Integer, primary_key=True)  # 如果第一個參數是一個字符串,那么使用該字符串作為字段名
    username = db.Column(db.String(80), unique=True)
    # 定義相關聯的表,backref為Address賦予了一個新的屬性,讓Address可以通過address.person找到user表
    addresses = db.relationship('Address', backref='person',
                                lazy='dynamic')

    # 可以手動初始化,也可以不做,那么會自動使用字段的變量名作為字段名
    def __init__(self, username, email):
        self.username = username
        self.email = email

    # 輸出字符串
    def __repr__(self):
        return '<User %r>' % self.username

class Address(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(50))
    # 指定外鍵
    person_id = db.Column(db.Integer, db.ForeignKey('person.id'))

#也可以直接創建表,一般用於多對多關系
tags = db.Table('uesrs',
    id = db.Column(db.Integer, primary_key=True) 
    username = db.Column(db.String(80), unique=True)
)

引入上下文

SQLAlchemy是一個全局對象,如果有多個應用程序的話,必須要讓SQLAlchemy對象知道當前服務於哪個app。

# 如果只有一個app,可以創建時初始化
app = Flask(__name__)

db = SQLAlchemy(app)

# 如果有多個應用
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

db = SQLAlchemy()
def create_app():
    app = Flask(__name__)
    # 這個函數其讀取app的配置參數,將和數據庫相關的配置加載到SQLAlchemy對象中
    db.init_app(app)
    return app

數據庫的操作

  • 創建和刪除表
# 刪除所有的表,bind參數可以指定為哪一個數據庫創建表,默認為__all__,所有的數據庫;
# app傳入是為了獲取初始化的相關參數,如果db已經初始化,則不需要傳入
db.drop_all(bind="",app=app)
# 創建所有的表,其參數和drop_all是一樣的
db.create_all()
  • 數據的增刪改查
# 首先創建一個實例
user = User(username='aaa')
# 插入一條數據,這時會發出一條insert語句,但是該事務還沒有提交,可以放棄
# 每個add操作都是一個數據
db.session.add(user)
# 批量添加數據
db.session.add_all([user1,user2])
# 刪除數據
db.session.delete(user1)
# 提交給數據庫
db.session.commit()
# 更新數據
User.query.filter_by(name='xxx').update({'name':'li'})

# 查詢query屬性
User.query.filter().all()
  • 過濾器的使用
# 常用的過濾器
filter()	把過濾器添加到原查詢上,返回一個新查詢
filter_by()	把等值過濾器添加到原查詢上,返回一個新查詢
limit()	    使用指定的值限定原查詢返回的結果
offset()	偏移原查詢返回的結果,返回一個新查詢
order_by()	根據指定條件對原查詢結果進行排序,返回一個新查詢
group_by()	根據指定條件對原查詢結果進行分組,返回一個新查詢
# 精確查詢
person = User.query.filter_by(name='aaa',id='23').all()
# 模糊查詢,
persons = User.query.filter(User.name.endswith('g')).all()
User.query.filter(User.id>3).all()

# 按username排序
User.query.order_by(User.username)
# 限制返回3個數據
User.query.limit(3).all()

# 條件查詢
# 邏輯非
User.query.filter(User.name!='xxx').all()
# 邏輯與
from sqlalchemy import and_
User.query.filter(and_(User.name!='xxx',User.address.endwith('g')).all()
# 邏輯或
User.query.filter(or_(User.name!='xxx',User.address.endwith('g'))).all()
# 取反,名字不是xxx的所有
User.query.filter(not_(User.name=='xxx')).all()
  • 執行器的使用
all()	        以列表形式返回查詢的所有結果
first()	        返回查詢的第一個結果,如果未查到,返回None
first_or_404()	返回查詢的第一個結果,如果未查到,返回404
get()	        返回指定主鍵對應的行,如不存在,返回None
get_or_404()	返回指定主鍵對應的行,如不存在,返回404
count()	        返回查詢結果的數量
paginate()	    返回一個Paginate對象,它包含指定范圍內的結果
# 使用主鍵查詢,id = 1
User.query.get(1)

數據庫的遷移

  • 我們可以使用create_all()函數來創建數據庫的表,不過在flask中有更加完善的管理工具flask-migrate;

  • 安裝

pip install flask-migrate
  • 實例
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate,MigrateCommand
from flask_script import Shell,Manager

app = Flask(__name__)
manager = Manager(app)
db = SQLAlchemy(app)

#第一個參數是Flask的實例,第二個參數是Sqlalchemy數據庫實例
migrate = Migrate(app,db) 
#manager是Flask-Script的實例,這條語句在flask-Script中添加一個db命令
manager.add_command('db',MigrateCommand)
# 生成相關的遷移文件,創建migrations文件夾,這個文件在項目的目錄下
python manage.py db init
# 生成遷移腳本,生成upgrade()和downgrade()函數的內容,這是將要執行的操作;
python manage.py db migrate -m '修改說明'
#更新數據庫
python manage.py db upgrade
# 如果需要歷史版本,回退
python manage.py db history # 先查詢歷史版本
# 執行回退
python manage.py db downgrade 版本號


免責聲明!

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



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