ORM 數據庫使用


使用 Flask-SQLAlchemy  來操作數據庫

1 配置

本文使用sqlite來作為例子演示,在config.py里面更新下數據庫的配置

import os basedir = os.path.abspath(os.path.dirname(__file__)) SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.db') SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')

Flask-SQLAlchemy會引用到 SQLALCHEMY_DATABASE_URI 來獲取數據庫的存儲位置,SQLAlchemy-migrate 會引用SQLALCHEMY_MIGRATE_REPO,移動的數據庫文件會放到這個目錄下

配置對象中還有一個很有用的選項,即 SQLALCHEMY_COMMIT_ON_TEARDOWN 鍵,將其設為 True時,每次請求結束后都會自動提交數據庫中的變動

 

完善數據庫基本配置之后,在app/__init__.py初始化數據庫引擎對象

from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config.from_object('config') db = SQLAlchemy(app) from app import views, models

這樣就初始化了一個db對象,並且引入models,models就是數據庫的描述模版,下面會介紹

 

2 設計數據庫model

如何用Flask-SQLAlchemy描述這張表?app/models.py

from app import db class User(db.Model): id = db.Column(db.Integer, primary_key=True) nickname = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) def __repr__(self): return '<User %r>' % (self.nickname)

 

 3 創建數據庫

配置好了,數據庫表也定義好了,接下來就是創建數據庫。創建一個創建數據庫的腳本,放到跟config.py同目錄下,命名為db_create.py。先安裝SQLAlchemy-migrate 

easy_install SQLAlchemy-migrate 安裝完成之后,編寫db_create.py

#!flask/bin/python from migrate.versioning import api from config import SQLALCHEMY_DATABASE_URI from config import SQLALCHEMY_MIGRATE_REPO from app import db import os.path db.create_all() if not os.path.exists(SQLALCHEMY_MIGRATE_REPO): api.create(SQLALCHEMY_MIGRATE_REPO, 'database repository') api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO) else: api.version_control(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, api.version(SQLALCHEMY_MIGRATE_REPO))

運行db_create.py創建數據庫,python ./db_create.py,創建成功后會生成如下文件

 

 

 3 數據遷移

models.py更新了,添加一張表,怎么更新數據庫,可以把每次數據庫結構的變動當作一次數據遷移

#!flask/bin/python import imp from migrate.versioning import api from app import db from config import SQLALCHEMY_DATABASE_URI from config import SQLALCHEMY_MIGRATE_REPO v = api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO) migration = SQLALCHEMY_MIGRATE_REPO + ('/versions/%03d_migration.py' % (v+1)) tmp_module = imp.new_module('old_model') old_model = api.create_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO) exec(old_model, tmp_module.__dict__) script = api.make_update_script_for_model(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO, tmp_module.meta, db.metadata) open(migration, "wt").write(script) api.upgrade(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO) v = api.db_version(SQLALCHEMY_DATABASE_URI, SQLALCHEMY_MIGRATE_REPO) print('New migration saved as ' + migration) print('Current database version: ' + str(v))

運行 python ./db_migrate.py
SQLAlchemy-migrate通過對比數據庫的結構(從app.db文件讀取)和models結構(從app/models.py文件讀取)的方式來創建遷移任務,兩者之間的差異將作為一個遷移腳本記錄在遷移庫中,遷移腳本知道如何應用或者撤銷一次遷移,所以它可以方便的升級或者降級一個數據庫的格式
 
        

 3 操作實戰

更新app/models.py

from app import db class User(db.Model): id = db.Column(db.Integer, primary_key=True) nickname = db.Column(db.String(64), index=True, unique=True) email = db.Column(db.String(120), index=True, unique=True) posts = db.relationship('Post', backref='author', lazy='dynamic') def __repr__(self): return '<User %r>' % (self.nickname) class Post(db.Model): id = db.Column(db.Integer, primary_key = True) body = db.Column(db.String(140)) timestamp = db.Column(db.DateTime) user_id = db.Column(db.Integer, db.ForeignKey('user.id')) def __repr__(self): return '<Post %r>' % (self.body)

運行 python ./db_migrate.py,查看數據庫磁盤結構

Users這張表並沒有posts字段,why?SQLAlchemy運行時會動態向Usrs插入posts字段,這樣訪問Users.posts會包含這個用戶發出的所有文章列表。這里relationship第二個參數backref='author',效果就是系統動態往Post插入author字段,這樣訪問post.author就能訪問到該文章作者的信息了

 
        

 3 操作數據庫

可以在線操作,也可以離線操作,只要在python文件里面

from app import db, models

 就可以操作數據庫了

from app import db, models
import datetime

@app.route('/testdb_addusers')
def testdb_addusers():
users = { 'Miguel', 'sysnap', 'helxx', 'xxxx'}

for name in users:
mail = name + '@email.com'
u = models.User(nickname=name, email=mail)
db.session.add(u)

p = models.Post(body='my first post!', timestamp=datetime.datetime.utcnow(), author=u)
db.session.add(p)

db.session.commit()

return "add user ok"


@app.route('/testdb_queryall')
def testdb_queryall():
users = models.User.query.all()
for u in users:
print u.email,u.nickname, u.posts.all()

return "xxxx"

 


免責聲明!

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



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