資料庫與flask
學習用SQLite 部署用MySQL (MySQL比較麻煩)
SQLite是小型文檔型的資料庫,支持SQL
ORM 介面可以串接任一種SQL的底層(代碼與底層數據庫的選擇無關 都可以用 需要一個object relational mapper(ORM)工具)
安裝
for flask SQLAlchemy ORM (課程)
pip install flask_sqlalchemy
pip install Flask-Migrate
創建資料庫(SQL command)
1.進入MySQL
terminal> mysql -u loot -p
輸入密碼
2.創建資料庫
mysql> create database tradingdesk(dbname);
3.使用資料庫
mysql>use tradingdesk;
4,創建資料庫
create table user (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(64) NOT NULL UNIQUE,passqord_hash VARCHAR(128) NOT NULL,email VARCHAR(64) NOT NULL);
5.顯示資料庫結構
desc user;
6.新增資料
insert into user(username,password_hash,email) values (“admin”,MD5(‘admin’),”admin@admin.com”);
7.顯示資料
select * from user;
SQL Alchemy 初始化
(教學用SQLite 部署用MySQL 但程式碼都可以用)
db=init_app(app)需要設置 app.con fig[‘SQLALCHEMY_DATABASE_URI’]
SQL Alchemy [user] table的實現
創建user table SQLAchemy的物件
- 建立models.py的文件
引入db
建立Class級別的物件User
並建立__repr__函數 方便顯示內容
2. 檢查
terminal進入python
%python3
>>>from twittor.models import User
>>>user = User(username=’admin’, email=’admin@admin.cin’,password_hash=’ededededede’)
>>>user
id=None, username=admin, email=admin@admin.cin,password, password_hashededededede
3.使用定義過的class user 去做資料庫的Migrate
所謂的Migration 是Class table 映射到實體資料庫中
並能對資料庫版本做維護
通過User代碼定義出User資料庫
並真正的將table表映射出來
先設置 使用Migration 的先行設定
要使用其db command
設定manager.py 使用Flask-Script(Using Flask-Script)
可以下命令列
後續並關掉警告訊息
app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’] = False
4.修改一下 讓app知道有這個 User Class Model
route.py / from twittor.models import User 在route.py
(引入讓app知道User Model)
init.py / form twittor.route import index, login
model.py / import db
所以在 init.py / form twittor.route import index, login時,就會呼叫route.py / from twittor.models import User,就會呼叫models.py/from twittor import db
db在__init__.py未實體化會出錯
因為順序實體化在後面 db = SQLAlchemy()
分階段的說
A.在route內import User (User Class在models內) app才會認識User Model
B.__init__內import route(牽涉models)
C.models內import db )(但db在__init__內還沒實體化,app還不知道db是什麼)
開始B的時候
import route 就A要先models import User
但是db還沒初始化
models User import db會出錯
改變執行順序db先實體化
再import route
才不會出錯
[這個浪費我些時間]
manage.py 與 manager.py,manager.py才是正確的
資料庫Migrate
5.開始Migrate command
5–1.初始化一個folder
python manager.py db init
生成migrations folder
5–2.migrate
python manager.py db migrate -m “create user” (-m message)
5–3.當前數據庫版本
python manager.py db current
5–4.migrate upgrade/downgrade (sqlite不支援drop刪除column這件事,但是MySQL支援 (替代方式用 刪除tradingdesk.db and 刪除migrations folder)
python manager.py db upgrade
python manager.py db downgrade(回到上一個版本)
如果是用MySQL 需先準備好MySQL Server / pip install pymysql
修改SQLALCHEMY_DATABASE_URI
pip install pymysql app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql:///root:root@localhost:3306/資料庫名稱'
sqlite 不支援只好刪除 migrations folder and database.db 重新執行上面命令(檔案管理員內執行)
6.新增關聯資料表
關聯資料表的意思是關聯存在的資料,例如欄位不能新增沒有在關聯資料表內的項目
透過db.ForeignKey(‘user.id’)去關聯資料user.id
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
tweets = db.relationship('Tweet', backref = 'author' ,lazy = 'dynamic')
這是一個訪問的方法,Tweet為class Tweet
lazy 這個用到的時候再解釋
create_time = db.Column(db.DateTime, default=datetime.utcnow)
以上這個先pip install datetime
default 預設值
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
used_id 欄位 需輸入user資料表有的id 才可以 user.id
重新執行5–1~5–4
把配置單獨拿出來
7.做更容易擴展程式的些改 config.py
單獨一個config.py文件,做集中化的管理
不是在__init__.py/create_app之中
把配置單獨拿出來
在config.py定義class config
定義一些class 級別的變量
如何使用config.py
在__init__.py / from twittor.config import Config
app.config.from_object(Config)
7–1.os絕對位置
sqlite:///:tradingdesk.db 這個是資料庫[相對位置]的目錄,絕對位置每台電腦不一樣,使用上會出問題
解決方式用os,取得config.py當前的路徑
import os
config_path = os.path.abspath(os.path.dirname(__file__))
__file__當前文件(指自己)
os.path.abspath絕對路徑
os.path.dirname(__file__)當前文件file的名字 (當前文件是config)
os.path.abspath(os.path.dirname(__file__))當前文件名字的絕對路逕
os.path.join( path, filename)
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(config_path, 'tradingdesk.db')
由於這個方式寫死DB及路徑,若是希望很方便的去修改,能透過環境變數的方式 os.environ.get(“”,””)
SQLALCHEMY_DATABASE_URI = os.environ.get(“DATABASE_URL”, “sqlite:///” + os.path.join(config_path, “tradingdesk.db”))
之後就可以非常方便的變更database的url
兩個改變的方式如下
1.export設置環境變量
export DATABASE_URL = ‘sqlite:///User/test.db’
2. 運行的時候設置環境變量
DATABASE_URL = ‘sqlite:///User/test.db’ python
刪除migrations folder 刪除.db 重新執行5–1~5–4
命令列數據庫操作
8 進入python
>>>from twittor import db, create_app
>>>app = craete_app()
>>>db
沒有內容沒有engine 是因為app沒有進入app context內
>>>app.app_context().push() 進入app context內
>>>db
有了engine 可以開始操作command
from twittor,models import User, Tweet 引入User Tweet Model
u = User(username=”admin”, email=”admin@admin.com”) 初始化一個Use實例
t = Tweet(body=’’this is first one”, user_id=2)
db.session.add(u) ‘新增
db.session.commit()
User.query.all() ‘查詢
User.query.get(1) ‘查詢id=1
刪除數據,要先知道要刪哪一條
t=Tweet.query.get(1)
db.session.delete(t) ‘刪除
db.session.commit()
更新修改
u=User.query.get(2)
u.email=”test1_new@admin.com”
db.session.commit()
多筆清除範例
tweets = Tweet.query.all()
for t in tweets:
db.session.delete(t)
users = User.query.all()
for u in users:
db.session.delete(u)
db.session.commit()
參考操作文件
其他選取方式範例
User.query.filter_by(username='peter').first()
User.query.order_by(User.username).all()
User.query.limit(1).all()