APIの勉強(まとめ・ソースコード解読(2/2))
ロジック側(python)
- run.py
-
importは同じ階層にしか効かない。
サブディレクトリをimportしたい場合はおまじないを使う。
pythonは、実行されたscriptと同じ階層にあるdirectoryを探して、その中に __init__.py
があると、其のフォルダの中をimport対象として認識する。__init__.py
は空でいい。 $ touch __init__.py
でいい。
python3 run.pyを実行することで、from app.app import app
つまり、appディレクトリの中の、app.pyの中から、def app()を持ってくる。
if __name__ = __main__ がTrueなので、
app.run()
が動き、appディレクトリの中の、app.pyの中から、def app()が作動する
はずなのだが、今回def app()が見つからないので、app =
Flask(__name__)
が動いているのかもしれない(?)
→appという変数をimportしているのではないか?
- app.py
from flask import Flask,render_template,request,session,redirect,url_for
from models.models import OnegaiContent
from models.models import User
from models.database import db_session
from datetime import datetime
from app import key
from hashlib import sha256
modelsディレクトリの中のmodelsからclass OnegaiContent,class Userをimportしている
databaseからdb_session(→変数)をimportしている
app = Flask(__name__)
app.secret_key = key.SECRET_KEY
Flaskを起動し、appにインスタンスを入れる。
appインスタンスのsecret_key に key.pyの変数SECRET_KEYを入れる。
@app.route("/")
@app.route("/index")
def index():
if "user_name" in session:
name = session["user_name"]
all_onegai = OnegaiContent.query.all()
return render_template("index.html",name=name,all_onegai=all_onegai)
else:
return redirect(url_for("top",status="logout"))
@app.route('/...')
というのは、このURLにユーザが入ってきたときに以下の関数を実行しろというものである
そんで、
- database.py
- DBに入れる
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import os
databese_file = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'onegai.db')
engine = create_engine('sqlite:///' + databese_file, convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,autoflush=False,bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
def init_db():
import models.models
Base.metadata.create_all(bind=engine)
from sqlalchemy import create_engine, Column, String, Integer from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker engine = create_engine('sqlite:///user.db')
# user.db というデータベースを使うという宣言です
Base = declarative_base()
# データベースのテーブルの親です
class User(Base):
# PythonではUserというクラスのインスタンスとしてデータを扱います
__tablename__ = 'users'
# テーブル名は users です
id = Column(Integer, primary_key=True, unique=True)
# 整数型のid をprimary_key として、被らないようにします
email = Column(String)
# 文字列の emailというデータを作ります
name = Column(String)
# 文字列の nameというデータを使います
def __repr__(self):
return "User<{}, {}, {}>".format(self.id, self.email, self.name)
Base.metadata.create_all(engine) # 実際にデータベースを構築します
SessionMaker = sessionmaker(bind=engine)
# Pythonとデータベースの経路です
session = SessionMaker()
# 経路を実際に作成しました
user1 = User(email="thisisme@test.com", name="Python")
# emailと nameを決めたUserのインスタンスを作りましょう(idは自動で1から順に振られます)
session.add(user1)
# user1 をデータベースに入力するための準備をします
session.commit()
# 実際にデータベースにデータを入れます。
- DBから出す
primary_keyで検索
例えば、idが2番目の人を取り出したいなら、
user = session.query(User).get(2)
としましょう。session.query(table名)
で、テーブルを指定して検索がかけられます。
primary_keyがidになっているので、get()の引数がidに合致するデータが取り出されます
値の大小で検索
idが3以上の人を探したいときには
user = session.query(User).filter(User.id >= 3).all()
print(user)
# [User<3, cobolisnotold@test.com, Cobol>, User<4, cplusminus@test.com, C>, User<5, kotlinissocute@test.com, Kotlin>, User<6, ilikeguido@test.com, Python>]
一致で検索
user = session.query(User).filter(User.name == "Python").all()
print(user)
# [User<1, thisisme@test.com, Python>, User<6, ilikeguido@test.com, Python>]
複数条件
user = session.query(User).filter(User.name == "Python", User.email == "thisisme@test.com").all()
print(user)
# [User<1, thisisme@test.com, Python>]
複数の条件を持たけることもでき、そのすべてが当てはまるもののみ返します。
いったんはこの程度で十分だと思います。
変更を加える
user = session.query(User).filter(User.name == "Python", User.email == "thisisme@test.com").all()
user.name = "Pythonista"
print(user)
# [User<1, thisisme@test.com, Pythonista>]
session.commit()
データを削除する
user = session.query(User).filter(User.name == "Python", User.email == "thisisme@test.com").all()
session.delete(user)
session.commit()
とすることでuserをデータベースから削除できます。
おわり