ORM 數據庫使用

使用 Flask-SQLAlchemy  來操做數據庫python

1 配置sql

本文使用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,移動的數據庫文件會放到這個目錄下flask

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

 

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



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就是數據庫的描述模版,下面會介紹app

 

2 設計數據庫modelpost

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

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更新了,添加一張表,怎麼更新數據庫,能夠把每次數據庫結構的變更看成一次數據遷移



運行 python ./db_migrate.py
SQLAlchemy-migrate經過對比數據庫的結構(從app.db文件讀取)和models結構(從app/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))
 

 3 操做實戰

更新app/models.py



運行 python ./db_migrate.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)

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"

相關文章
相關標籤/搜索