Flask Turtoial(資料庫)
Flask-SQLAlchemy關係型資料庫對映器 /ORM(全全稱Object Relation Mapping)
ORMs允許應用程式使用高階實體(類User,物件yang, 方法User.query.filter_by(username='xxx').first()),而不是表和SQL來管理資料庫.執行在物件的操作會被ORMs翻譯成資料庫命令,這意味著不需要使用SQL語言
models.py from app import db class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) password_hash = db.Column(db.String(128)) def __repr__(self): return '<User {}>'.format(self.username)
repr的作用
>>> u = User(username='susan', email='[email protected]')
>>> u
<User susan>
flask db init 生成migrations資料夾,對應有資料庫遷移的版本
flask db migrate -m "add users table" # 生成遷移指令碼,但不對資料庫進行更改
flask db upgrade # 應用更改
如果想回退的話流程是:
flask db downgrade 回退修改
手動刪除對應的遷移指令碼
定義Post類
app/models.py class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) password_hash = db.Column(db.String(128)) # 在一這一側定義relationship posts = db.relationship('Post', backref='author', lazy='dynamic') def __repr__(self): return '<User {}>'.format(self.username) class Post(db.Model): id = db.Column(db.Integer, primary_key=True) body = db.Column(db.String(140)) timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow) user_id = db.Column(db.ForeignKey('user.id')) def __repr__(self): return '<Post {}>'.format(self.body)
Post類代表使用者撰寫的blog,timestamp可以提供給我們按時間檢索帖子的方法,因此預設defaut使用datetime.utcnow方法傳遞,而不是返回結果.
如何新增使用者? 比如叫john
python
>>> from app import db
>>> from app.models import User, Post
>>> u = User(username='john', email='[email protected]')
>>> db.session.add(u)
>>> db.session.commit()
如何查詢所有使用者?
>>> users = User.query.all()
>>> users
[<User john>, <User susan>]
>>> for u in users:
print(u.id , u.username)
1 john
2 susan
當你知道使用者id的時候呢?如何查詢?
u = User.query.get(1)
>>> u
<User john>
新增一篇文章呢?
u = User.query.get(1)
p = Post(body='my first post!', author=u)
db.session.add(p)
db.session.cmmit()
由於我之前在User類中,定義過posts欄位,即db.relationship,
在關聯中,設定了一個虛擬的欄位author(backref=author),這樣我可使用(author=user)來生成post例項
其他
>>> # get all posts written by a user
>>> u = User.query.get(1)
>>> u
<User john>
# 這裡注意 u.posts方法使用的是dynamic查詢方法
>>> posts = u.posts.all()
>>> posts
[<Post my first post!>]
>>> # same, but with a user that has no posts
>>> u = User.query.get(2)
>>> u
<User susan>
>>> u.posts.all()
[]
>>> # print post author and body for all posts
>>> posts = Post.query.all()
>>> for p in posts:
... print(p.id, p.author.username, p.body)
...
1 john my first post!
# get all users in reverse alphabetical order
>>> User.query.order_by(User.username.desc()).all()
[<User susan>, <User john>]
刪除測試資料
>>> users = User.query.all()
>>> for u in users:
... db.session.delete(u)
...
>>> posts = Post.query.all()
>>> for p in posts:
... db.session.delete(p)
...
>>> db.session.commit()
Shell上下文
在python直譯器中,想要獲取app的物件,需要先import
而shell上下文可以直接啟動python直譯器,並匯入變數
只需要在microblog.py啟動檔案中寫入:
from app import app, db
from app.models import User, Post
@app.shell_context_processor
def make_shell_context():
return {'db': db, 'User': User, 'Post': Post}
User有哪些欄位? Post有哪些欄位?哪些欄位需要索引? 那些需要唯一?外來鍵在那定義?外來鍵寫在哪? 需要放在Column裡面嗎?裡的值填什麼? relationship在哪定義?需要放在Column裡面嗎?寫法是什麼?
在Post欄位中的,欄位timestamp呼叫的是什麼方法? 什麼庫中的什麼? 是值還是方法? 為什麼要這麼呼叫?
@app.shell_context_processor 裝飾符為shell上下文註冊功能.
當flask shell執行的時候,呼叫此函式並註冊函式中的項