定義
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
or
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy()
db.init_app(app)
config[config_name].init_app(app) # config.py里,指定了數據庫文件,比如 mysql:///, sqlite:///
關系
一對多(one-to-many)
關系使用relationship()
函數表示。然而外鍵必須用類sqlalchemy.schema.ForeignKey
單獨聲明:
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
addresses = db.relationship('Address', backref='person',
lazy='dynamic')
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'))
一對一
只需要添加uselist=False
屬性
class Person(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
addresses = db.relationship('Address', backref='person',
lazy='dynamic', uselist=False)
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'))
多對多關系(many-to-many)
如果您想要用多對多關系,您需要定義一個用于關系的輔助表。對于這個輔助表, 強烈建議不使用模型,而是采用一個實際的表:
tags = db.Table('tags',
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
db.Column('page_id', db.Integer, db.ForeignKey('page.id'))
)
class Page(db.Model):
id = db.Column(db.Integer, primary_key=True)
tags = db.relationship('Tag', secondary=tags,
backref=db.backref('pages', lazy='dynamic'))
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
多對多關系使用(在使用多對多關系時需要先將相對應的對象查詢出來):
- 添加關系
page_1 = Page()
tag_1 = Tag()
db.session.add(page_1)
db.session.add(tag_1)
db.session.commit()
# 添加對應關系
page_1.tags.append(tag_1)
db.session.add(page_1)
db.session.commit()
- 刪除關系
page_1.tags.remove(tag_1)
db.session.add(page_1)
db.session.commit()
- 查詢
# 列出所有的tags數組
page_1.tags.all()
操作
models.py
定義如下:
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
users = db.relationship('User', backref='role', lazy="dynamic")
def __init__(self, name):
self.name = name
def __repr__(self):
return '<Role %r>' % self.name
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __init__(self, username, role):
self.username = username
self.role = role
def __repr__(self):
return '<User %r>' % self.username
創建 刪除表
db.create_all()
db.drop_all()
插入行
admin_role = Role(name='Admin')
db.session.add(admin_role)
db.session.commit()
修改行
admin_role.name = 'Administartor'
db.session.add(admin_role)
db.session.commit()
刪除行
db.session.delete(admin_role)
db.session.commit()
查詢行
Flask-SQLAlchemy為每個模型類都提供了query
對象。
Role.query.all()
User.query.filter_by(role=user_role).all()
常用的SQLAlchemy查詢過濾器
方法 | 說明 |
---|---|
filter() | 把過濾器添加到原查詢上,返回一個新查詢 |
filter_by() | 把等值過濾器添加到原查詢上,返回一個新查詢 |
limit() | 使用指定的值限制原查詢返回的結果數量,返回一個新查詢 |
offset() | 偏移原查詢返回的結果,返回一個新查詢 |
order_by() | 根據指定條件對原查詢結果進行排序,返回一個新查詢 |
group_by() | 根據指定條件對原查詢結果進行分組,返回一個新查詢 |
方法 | 說明 |
---|---|
all() | 以列表形式返回查詢的所有結果 |
first() | 返回查詢的第一個結果,如果沒有結果,則返回 None |
first_or_404() | 返回查詢的第一個結果,如果沒有結果,則終止請求,返回 404 錯誤響應 |
get() | 返回指定主鍵對應的行,如果沒有對應的行,則返回 None |
get_or_404() | 返回指定主鍵對應的行,如果沒找到指定的主鍵,則終止請求,返回 404 錯誤響應 |
count() | 返回查詢結果的數量 |
paginate() | 返回一個 Paginate 對象,它包含指定范圍內的結果 |
常用的SQLAlchemy查詢執行函數
方法 | 說明 |
---|---|
all() | 以列表形式返回查詢的所有結果 |
first() | 返回查詢的第一個結果,如果沒有結果,則返回 None |
first_or_404() | 返回查詢的第一個結果,如果沒有結果,則終止請求,返回 404 錯誤響應 |
get() | 返回指定主鍵對應的行,如果沒有對應的行,則返回 None |
get_or_404() | 返回指定主鍵對應的行,如果沒找到指定的主鍵,則終止請求,返回 404 錯誤響應 |
count() | 返回查詢結果的數量 |
paginate() | 返回一個 Paginate 對象,它包含指定范圍內的結果 |
Flask 數據庫遷移工具 flask-migrate
僅當數據庫表不存在時,Flask-SQLAlchemy 才會根據模型進行創建。因此,更新表的唯一方式就是先刪除舊表,不過這樣做會丟失數據庫中的所有數據
manage.py
添加db命令
from flask_migrate import Migrate, MigrateCommand
migrate = Migrate(app, db)
manager.add_command("db", MigrateCommand)
第一次使用:
- 初始化:
python manage.py db init
這個命令會在項目下創建 migrations 文件夾,所有遷移腳本都存放其中。 - 創建第一個版本:
python manage.py db migrate -m "initial migration"
檢查migrations/versions,檢查里面表格及字段 - 運行升級
python manage.py db upgrade
,會把項目使用的數據庫文件,更新為新的表格、字段,同時保留數據
更新:
- 更新表格的字段
- 再次運行一下
db migrate -m 'xx'
-> 相當于commit 更新到/migrate目錄 -
db upgrade
-> 數據庫會更新