Python 自習室に参加してきた
3 月に一回参加しているけど、Python 自習室という名前になってからは初めての参加。
場所はアクセンス・テクノロジー様の大阪オフィス。いつもありがとうございます<(_ _)>
前回は Paver でオレオレツールを作って、今回は何しようかなーと迷ってたが、Flask を試してみようかと思っていじった。
Welcome | Flask (A Python Microframework)
サンプルを実行してみたら、あっさり動いた。
それだけじゃあれなので、SQLAlchemy と連携してみた。
Flask-SQLAlchemy というのがあるのは知っているが、個人的にスキーマ定義は sql ファイルでやりたい。
SQLAlchemy にテーブル定義を書くのではなく、定義を自動的にロードするのはこちらを参考にした。
今日も明日もググったー: autoload declarative sqlalchemy
構成はこんな感じ。
|-- app.cfg |-- app.py |-- model | |-- __init__.py | |-- base.py | `-- entries.py |-- schema.sql |-- static | `-- style.css `-- templates |-- layout.html |-- login.html `-- show_entries.html
app.cfg
SQLALCHEMY_ECHO = False DEBUG = True SECRET_KEY = 'development key' USERNAME = 'admin' PASSWORD = 'default'
schema.sql
drop table if exists entries; create table entries ( id integer primary key autoincrement, title text not null, text text not null );
app.py
from flask import Flask, request, session, redirect, url_for, abort, \ render_template, flash from model.base import db_session from model.entries import Entry app = Flask(__name__) app.config.from_pyfile('app.cfg') @app.route('/') def show_entries(): entries = db_session.query(Entry).all() return render_template('show_entries.html', entries=entries) @app.route('/login', methods=['GET', 'POST']) def login(): error = None if request.method == 'POST': if request.form['username'] != app.config['USERNAME']: error = 'Invalid username' elif request.form['password'] != app.config['PASSWORD']: error = 'Invalid password' else: session['logged_in'] = True flash('You were logged in') return redirect(url_for('show_entries')) return render_template('login.html', error=error) @app.route('/logout') def logout(): session.pop('logged_in', None) flash('You were logged out') return redirect(url_for('show_entries')) @app.route('/add', methods=['POST']) def add_entry(): if not session.get('logged_in'): abort(401) entry = Entry(title=request.form['title'], text=request.form['text']) db_session.add(entry) db_session.commit() flash('New entry was successfully posted') return redirect(url_for('show_entries')) if __name__ == '__main__': app.run()
model/base.py
from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.ext.declarative import declarative_base uri = 'sqlite:////tmp/flaskr.db' engine = create_engine(uri, convert_unicode=True) db_session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine)) Base = declarative_base(bind=engine) Base.query = db_session.query_property()
model/entries.py
from base import Base class Entry(Base): __tablename__ = 'entries' __table_args__ = { 'autoload': True } def __init__(self, title=None, text=None): self.title = title self.text = text def __repr__(self): return '<Entry(%s, %s)>' % (self.title, self.text)
こういう普段試したいと思いつつ中々実行に移せないのをじっくり時間をとって、試す事ができるのは素晴らしいと思う。