### 使用Flask-SQLAlchemy創(chuàng)建模型與表的映射:
1. 模型需要繼承自`db.Model`,然后需要映射到表中的屬性晦炊,必須寫成`db.Column`的數(shù)據(jù)類型苦囱。
2. 數(shù)據(jù)類型:
????* `db.Integer`代表的是整形.
????* `db.String`代表的是`varchar`嗅绸,需要指定最長(zhǎng)的長(zhǎng)度。
????* `db.Text`代表的是`text`撕彤。
3. 其他參數(shù):
????* `primary_key`:代表的是將這個(gè)字段設(shè)置為主鍵鱼鸠。
????* `autoincrement`:代表的是這個(gè)主鍵為自增長(zhǎng)的猛拴。
????* `nullable`:代表的是這個(gè)字段是否可以為空,默認(rèn)可以為空蚀狰,可以將這個(gè)值設(shè)置為`False`愉昆,在數(shù)據(jù)庫(kù)中,這個(gè)值就不能為空了麻蹋。
4. 最后需要調(diào)用`db.create_all`來將模型真正的創(chuàng)建到數(shù)據(jù)庫(kù)中跛溉。
### Flask-SQLAlchemy數(shù)據(jù)的增、刪扮授、改芳室、查:
1. 增:
????```
????# 增加:
????article1 = Article(title='aaa',content='bbb')
????db.session.add(article1)
????# 事務(wù)
????db.session.commit()
????```
2. 查:
????```
????# 查
????# select * from article where article.title='aaa';
????article1 = Article.query.filter(Article.title == 'aaa').first()
????print 'title:%s' % article1.title
????print 'content:%s' % article1.content
????```
3. 改:
????```
????# 改:
????# 1. 先把你要更改的數(shù)據(jù)查找出來
????article1 = Article.query.filter(Article.title == 'aaa').first()
????# 2. 把這條數(shù)據(jù),你需要修改的地方進(jìn)行修改
????article1.title = 'new title'
????# 3. 做事務(wù)的提交
????db.session.commit()
????```
4. 刪:
????```
????# 刪
????# 1. 把需要?jiǎng)h除的數(shù)據(jù)查找出來
????article1 = Article.query.filter(Article.content == 'bbb').first()
????# 2. 把這條數(shù)據(jù)刪除掉
????db.session.delete(article1)
????# 3. 做事務(wù)提交
????db.session.commit()
????```
### Flask-SQLAlchemy外鍵及其關(guān)系:
1. 外鍵:
????```
????class User(db.Model):
????????__tablename__ = 'user'
????????id = db.Column(db.Integer,primary_key=True,autoincrement=True)
????????username = db.Column(db.String(100),nullable=False)
????class Article(db.Model):
????????__tablename__ = 'article'
????????id = db.Column(db.Integer, primary_key=True, autoincrement=True)
????????title = db.Column(db.String(100),nullable=False)
????????content = db.Column(db.Text,nullable=False)
????????author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
????????author = db.relationship('User',backref=db.backref('articles'))
????```
2. `author = db.relationship('User',backref=db.backref('articles'))`解釋:
????* 給`Article`這個(gè)模型添加一個(gè)`author`屬性刹勃,可以訪問這篇文章的作者的數(shù)據(jù)堪侯,像訪問普通模型一樣。
????* `backref`是定義反向引用荔仁,可以通過`User.articles`訪問這個(gè)模型所寫的所有文章伍宦。
3. 多對(duì)多:
????* 多對(duì)多的關(guān)系,要通過一個(gè)中間表進(jìn)行關(guān)聯(lián)乏梁。
????* 中間表次洼,不能通過`class`的方式實(shí)現(xiàn),只能通過`db.Table`的方式實(shí)現(xiàn)遇骑。
????* 設(shè)置關(guān)聯(lián):`tags = db.relationship('Tag',secondary=article_tag,backref=db.backref('articles'))`需要使用一個(gè)關(guān)鍵字參數(shù)`secondary=中間表`來進(jìn)行關(guān)聯(lián)卖毁。
????* 訪問和數(shù)據(jù)添加可以通過以下方式進(jìn)行操作:
????????- 添加數(shù)據(jù):
????????????```
????????????article1 = Article(title='aaa')
????????????article2 = Article(title='bbb')
????????????tag1 = Tag(name='111')
????????????tag2 = Tag(name='222')
????????????article1.tags.append(tag1)
????????????article1.tags.append(tag2)
????????????article2.tags.append(tag1)
????????????article2.tags.append(tag2)
????????????db.session.add(article1)
????????????db.session.add(article2)
????????????db.session.add(tag1)
????????????db.session.add(tag2)
????????????db.session.commit()
????????????```
????????- 訪問數(shù)據(jù):
????????????```
????????????article1 = Article.query.filter(Article.title == 'aaa').first()
????????????tags = article1.tags
????????????for tag in tags:
????????????????print tag.name
????????????```
### Flask-Script的介紹與安裝:
1. Flask-Script:Flask-Script的作用是可以通過命令行的形式來操作Flask。例如通過命令跑一個(gè)開發(fā)版本的服務(wù)器质蕉、設(shè)置數(shù)據(jù)庫(kù)势篡,定時(shí)任務(wù)等。
2. 安裝:首先進(jìn)入到虛擬環(huán)境中模暗,然后`pip install flask-script`來進(jìn)行安裝。
3. 如果直接在主`manage.py`中寫命令念祭,那么在終端就只需要`python manage.py command_name`就可以了兑宇。
4. 如果把一些命令集中在一個(gè)文件中,那么在終端就需要輸入一個(gè)父命令粱坤,比如`python manage.py db init`隶糕。
5. 例子:
????```
????from flask_script import Manager
????from flask_script_demo import app
????from db_scripts import DBManager
????manager = Manager(app)
????# 和數(shù)據(jù)庫(kù)相關(guān)的操作,我都放在一起
????@manager.command
????def runserver():
????????print '服務(wù)器跑起來了!!!!!'
????manager.add_command('db',DBManager)
????if __name__ == '__main__':
????????manager.run()
????```
6. 有子命令的例子:
????```
????#encoding: utf-8
????from flask_script import Manager
????DBManager = Manager()
????@DBManager.command
????def init():
????????print '數(shù)據(jù)庫(kù)初始化完成'
????@DBManager.command
????def migrate():
????????print '數(shù)據(jù)表遷移成功'
????```
### 分開`models`以及解決循環(huán)引用:
1. 分開models的目的:為了讓代碼更加方便的管理站玄。
2. 如何解決循環(huán)引用:把`db`放在一個(gè)單獨(dú)的文件中枚驻,切斷循環(huán)引用的線條就可以了。
### Flask-Migrate的介紹與安裝:
1. 介紹:因?yàn)椴捎胉db.create_all`在后期修改字段的時(shí)候株旷,不會(huì)自動(dòng)的映射到數(shù)據(jù)庫(kù)中再登,必須刪除表尔邓,然后重新運(yùn)行`db.craete_all`才會(huì)重新映射,這樣不符合我們的需求锉矢。因此flask-migrate就是為了解決這個(gè)問題梯嗽,她可以在每次修改模型后,可以將修改的東西映射到數(shù)據(jù)庫(kù)中沽损。
2. 首先進(jìn)入到你的虛擬環(huán)境中灯节,然后使用`pip install flask-migrate`進(jìn)行安裝就可以了。
3. 使用`flask_migrate`必須借助`flask_scripts`绵估,這個(gè)包的`MigrateCommand`中包含了所有和數(shù)據(jù)庫(kù)相關(guān)的命令炎疆。
4. `flask_migrate`相關(guān)的命令:
????* `python manage.py db init`:初始化一個(gè)遷移腳本的環(huán)境,只需要執(zhí)行一次国裳。
????* `python manage.py db migrate`:將模型生成遷移文件磷雇,只要模型更改了,就需要執(zhí)行一遍這個(gè)命令躏救。
????* `python manage.py db upgrade`:將遷移文件真正的映射到數(shù)據(jù)庫(kù)中唯笙。每次運(yùn)行了`migrate`命令后,就記得要運(yùn)行這個(gè)命令盒使。
5. 注意點(diǎn):需要將你想要映射到數(shù)據(jù)庫(kù)中的模型崩掘,都要導(dǎo)入到`manage.py`文件中,如果沒有導(dǎo)入進(jìn)去少办,就不會(huì)映射到數(shù)據(jù)庫(kù)中苞慢。
6. `manage.py`的相關(guān)代碼:
????```
????from flask_script import Manager
????from migrate_demo import app
????from flask_migrate import Migrate,MigrateCommand
????from exts import db
????from models import Article
????# init
????# migrate
????# upgrade
????# 模型? ->? 遷移文件? ->? 表
????manager = Manager(app)
????# 1. 要使用flask_migrate,必須綁定app和db
????migrate = Migrate(app,db)
????# 2. 把MigrateCommand命令添加到manager中
????manager.add_command('db',MigrateCommand)
????if __name__ == '__main__':
????????manager.run()
????```