やるサイト
virtualenvでflask用の環境用意
virtualenvのインストールと使い方はここ参照。
$ mkvirtualenv flaski
$ workon flaski
インストール
(flaski):flask_test hoge$ pip install flask
(flaski):flask_test hoge$ pip install sqlalchemy
ローカルでwebサーバー立てて、ブラウザにHello Worldを表示。
from flask import Flask
app = Flask(__name__)
# http://127.0.0.1:5000をルートとして、("")の中でアクセスポイント指定
# @app.route("hoge")などで指定すると、http://127.0.0.1:5000/hogeでの動作を記述できる。
@app.route("/")
def hello():
return "Hello World!"
if __name__ == "__main__":
# webサーバー立ち上げ
app.run()
を作り、python app.py
で実行すると、以下が標準出力に表示される。
(flaski)hoge:src hoge$ python app.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
ブラウザでhttp://127.0.0.1:5000/
を打ち込むと以下が表示される。
SQLAlchemyを用いたSQLiteの操作
ファイル構成
├── flaski
│ ├── __init__.py
│ ├── database.py
│ └── models.py
├── do_create.py
└── do_insert.py
各スクリプトと動作確認
# -*- coding: utf-8 -*-
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import os
# wiki.dbという名前のdbファイルの作成を指定
databese_file = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'wiki.db')
# sqlliteを指定して、テーブルのcreateを指定。
engine = create_engine('sqlite:///' + databese_file, convert_unicode=True)
# bindにテーブルcreateを指定。
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
# declarative_baseのインスタンス生成。
Base = declarative_base()
# 実行用のセッション格納?
Base.query = db_session.query_property()
def init_db():
import flaski.models
# Baseの内容でcreate実行?
Base.metadata.create_all(bind=engine)
# -*- coding: utf-8 -*-
from sqlalchemy import Column, Integer, String, Text, DateTime
from flaski.database import Base
from datetime import datetime
class WikiContent(Base):
__tablename__ = 'wikicontents' # テーブル名
id = Column(Integer, primary_key=True) # カラム1(id)
title = Column(String(128), unique=True) # カラム2(title)
body = Column(Text) # カラム3(body)
date = Column(DateTime, default=datetime.now()) # カラム4(date) デフォルト現在日時を設定
def __init__(self, title=None, body=None, date=None):
self.title = title
self.body = body
self.date = date
def __repr__(self):
return '<Title %r>' % (self.title)
from flaski.database import init_db
# テーブルのクリエイト
init_db()
do_create.pyを実行することで、flaskiディレクトリの下にwiki.dbが出来上がる。
中身を確認してみる。
$ > (flaski)hoge:flaski hoge$ sqlite3 wiki.db
SQLite version 3.8.5 2014-08-15 22:37:57
Enter ".help" for usage hints.
sqlite> .schema
CREATE TABLE wikicontents (
id INTEGER NOT NULL,
title VARCHAR(128),
body TEXT,
date DATETIME,
PRIMARY KEY (id),
UNIQUE (title)
);
from flaski.database import init_db
from flaski.database import db_session
from flaski.models import WikiContent
# idには連番。title、textを指定。dateは日時が勝手に入る(model.pyのデフォルト設定により)
c1 = WikiContent("Flask", "micro framework") # カラム1:'Flask' カラム2:'micro framework'を指定してインスタンス作成
db_session.add(c1) # insert実行
db_session.commit() # commit実行
c2 = WikiContent("python", "pppython") # 以下同上
c3 = WikiContent("kobito", "kakure-momojiri")
db_session.add(c2)
db_session.add(c3)
db_session.commit()
さっきのテーブルを確認してみる。
(flaski)hoge:flaski hoge$ sqlite3 wiki.db
SQLite version 3.8.5 2014-08-15 22:37:57
Enter ".help" for usage hints.
sqlite> select * from wikicontents;
1|Flask|micro framework|2016-05-14 15:04:24.246057
2|python|pppython|2016-05-14 15:04:24.246057
3|kobito|kakure-momojiri|2016-05-14 15:04:24.246057
3レコードインサートされていることがわかる。
参考
flaskとSQLiteを連携して、データのGET
さっきのSQLiteに作ったテーブルの値を使って、Webページを表示する。
ソースコード
ファイル構成
├── flaski
│ ├── __init__.py
│ ├── database.py
│ └── models.py
├── app.py
├── static
│ └── snake.jpg
└── templates
├── index.html
├── layout.html
└── show_content.html
各スクリプト
# -*- coding: utf-8 -*-
"""
Using SQLAlchemy and Flask get db record.(GET)
"""
from flask import Flask, render_template, abort
from flaski.models import WikiContent
app = Flask(__name__)
app.config['DEBUG'] = True
# 起動されたサーバーの/にアクセスした時の挙動を記述。
# @app.route("/hoge")で記述すれば、http://127.0.0.1:5000/aaでアクセスした時の挙動を記述できる。
@app.route("/")
def hello():
contents = WikiContent.query.all()
# index.htmlにcontensを引数に渡して実行。
return render_template("index.html", contents=contents)
#/<title>を指定することで、index.htmlのtitle=content.titleを指定している。methods=["GET"]で、GETリクエストを指定。
@app.route("/<title>", methods=["GET"])
def show_content(title):
"""
:param title:modelに対するクエリ文字列
:return:
"""
# wikicontentテーブルから、titleでフィルタ(where指定して取得) firstは1行だけ取得するの意味。
# all()だと、結果を複数リスト形式で取得する。
content = WikiContent.query.filter_by(title=title).first()
if content is None:
abort(404)
# show_content.htmlを表示。引数にcontentを渡す。
return render_template("show_content.html", content=content)
if __name__ == "__main__":
# サーバーの起動
app.run()
{% extends "layout.html" %}
{% block body %}
<h1>Flaski</h1>
<!-- snake.jpgの表示-->
<img src="{{url_for('static', filename='snake.jpg')}}" alt="snake"/>
<ul>
<!-- 引数で渡されたcontentsのforループ-->
{% for content in contents %}
<!-- show_content.htmlを実行。+ {{content.title}}を表示。-->
<li><a href="{{url_for('show_content', title=content.title)}}">{{content.title}}</a></li>
{% endfor%}
</ul>
{% endblock %}
{% extends "layout.html" %}
{% block body %}
<!-- contentの内容を使って表示-->
<h1>{{content.title}}</h1>
<div>{{content.body}}</div>
<p>{{content.date}}</p>
<div>{{content.body}}</div>
{% endblock %}
ここまでで、http://127.0.0.1:5000 で以下のページが表示される。
それぞれのリンクをクリックでSQLiteの内容が表示される。
例えばpythonのリンクを踏むと、以下のような感じ。
SQLiteのpythonの内容を使って、表示されている。(GETができた)
以下のid=2の内容。
(flaski)hoge:flaski hoge$ sqlite3 wiki.db
SQLite version 3.8.5 2014-08-15 22:37:57
Enter ".help" for usage hints.
sqlite> select * from wikicontents;
1|Flask|micro framework|2016-05-14 15:04:24.246057
2|python|pppython|2016-05-14 15:04:24.246057
3|kobito|kakure-momojiri|2016-05-14 15:04:24.246057
APIのpostでSQLiteのテーブルに挿入/更新(POST)
SQLiteのテーブルに対し、insertとupdateを実行してみる。
ファイル構成
├── flaski
│ ├── __init__.py
│ ├── database.py
│ └── models.py
└── app.py
# -*- coding: utf-8 -*-
from flask import Flask, render_template, abort, request
from flaski.models import WikiContent
from flaski.database import db_session
from datetime import datetime
app = Flask(__name__)
app.config['DEBUG'] = True
@app.teardown_request
def shutdown_session(exception=None):
db_session.remove()
@app.route("/")
def hello():
contents = WikiContent.query.all()
return render_template("index.html", contents=contents)
@app.route("/<title>", methods=["GET"])
def show_content(title):
content = WikiContent.query.filter_by(title=title).first()
if content is None:
abort(404)
return render_template("show_content.html", content=content)
@app.route("/<title>", methods=["POST"])
def post_content(title=None):
if title is None:
abort(404)
content = WikiContent.query.filter_by(title=title).first()
# contentが取得できていなければinsertするため、WikiContentのインスタンスを生成
if content is None:
content = WikiContent(title,
request.form["body"]
)
# contentが取得できていればupdateするため、bodyの内容とdatetime=現在時刻をセット
else:
content.body = request.form["body"]
content.date = datetime.now()
# contentの内容をaddしてcommit
db_session.add(content)
db_session.commit()
return content.body
if __name__ == "__main__":
app.run()
この状態で、app.pyを実行しておく。
コンソール上で、httpリクエストをするため、pip install httpieでhttpieをインストールしておく。
# body=test from httpie を指定して更新
http --form POST http://localhost:5000/httpie body="test from httpie"
中身を確認してみると、id=4のレコードが追加された。
sqlite> select * from wikicontents;
1|Flask|micro framework|2016-05-14 15:04:24.246057
2|python|pppython|2016-05-14 15:04:24.246057
3|kobito|kakure-momojiri|2016-05-14 15:04:24.246057
4|httpie|test from httpie|2016-05-14 19:32:12.075871
今度は更新してみる。
# body=modified from httpie を指定して更新
http --form POST http://localhost:5000/httpie body="modified from httpie"
sqlite> select * from wikicontents;
1|Flask|micro framework|2016-05-14 15:04:24.246057
2|python|pppython|2016-05-14 15:04:24.246057
3|kobito|kakure-momojiri|2016-05-14 15:04:24.246057
4|httpie|modified from httpie|2016-05-14 19:35:40.904904
更新されてる。
この状態で、http://localhost:5000 を確認するとhttpieが追加されている。
httpieをクリックすると、ちゃんと更新した状態で取得できていることがわかる。
POSTできました。