BETA

flask-sqlalchemy備忘

投稿日:2020-07-12
最終更新:2020-07-18
from flask import Flask  
from flask_sqlalchemy import SQLAlchemy  

app = Flask(__name__)  
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'  
db = SQLAlchemy(app)  


class User(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    username = db.Column(db.String(80), unique=True, nullable=False)  
    email = db.Column(db.String(120), unique=True, nullable=False)  

    def __repr__(self):  
        return '<User %r>' % self.username  

公式のquickstart

公式より。
def __repr__(self):以下は,出力結果なので,なくてもいい。

このファイルを,app.pyとした場合,他のファイルではfrom appとする。

create table

>>> from app import db  
>>> db.create_all()  

テーブルを作成するときは,インタラクティブシェルで上記を実行する。

insert

from app import Person,Address,db  

admin = Person(name='admin')  
db.session.add(admin)  
db.session.commit()  

commit()しないと反映されない。

read

from app import Person,Address,db  

print(Person.query.all())  

queryの仕方はいろいろある。

公式のqueries

order_by desc

print(Person.query.order_by(Person.name.desc()).all()

あいまい検索

print(Person.query.filter(Person.name.like("%up%")).all())

delete

from app import Person,Address,db  

user = db.session.query(Person).filter_by(name="bbb").first()  
db.session.delete(user)  
db.session.commit()  

特定のレコードをqueryしてから,deleteメソッドを使う。

update

from app import Person,Address,db  

user = db.session.query(Person).filter_by(name="bbb").first()  
user.name = "updated"  
db.session.add(user)  
db.session.commit()  

特定のレコードをqueryしてから,変数を上書きして,insertと同じaddメソッドを使う。

公式

公式のuser-guide

公式のconfig

relation

from datetime import datetime  


class Post(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    title = db.Column(db.String(80), nullable=False)  
    body = db.Column(db.Text, nullable=False)  
    pub_date = db.Column(db.DateTime, nullable=False,  
        default=datetime.utcnow)  

    category_id = db.Column(db.Integer, db.ForeignKey('category.id'),  
        nullable=False)  
    category = db.relationship('Category',  
        backref=db.backref('posts', lazy=True))  

    def __repr__(self):  
        return '<Post %r>' % self.title  


class Category(db.Model):  
    id = db.Column(db.Integer, primary_key=True)  
    name = db.Column(db.String(50), nullable=False)  

    def __repr__(self):  
        return '<Category %r>' % self.name  

この例では,categoryが親で,postが子。
子であるpostの方に,以下の設定をしている。

    category_id = db.Column(db.Integer, db.ForeignKey('category.id'),  
        nullable=False)  
    category = db.relationship('Category',  
        backref=db.backref('posts', lazy=True))  

1行目のForeignKeyで,category_idというフィールドを作り,categoryモデル(テーブル)のidフィールドとのrelationを設定している。
backrefで設定したpostsで,postsをフィールド名のようにして,親であるcategoryの方から,アクセスすることができる。

from app import Post,Category,db  
from sqlalchemy.orm import joinedload  

query = Category.query.options(joinedload('posts'))  
for category in query:  
    print(category, category.posts[0].body)  

joinedloadをimportして,同名のjoinedloadメソッドに,backrefで設定したフィールド名?を入れる。
これで,親のCategoryモデルから,なんとなくアクセスできるようになる。
for category in query:で,dbのcategoryテーブルから,1行1行を読み込んでいると思う。
それで,category.posts[]に,配列で,当該category行にひもづいた(relationしている)postテーブルの各行が入っている。
category.posts[0].bodyで,先頭行のbodyフィールドの内容(値)を取得できる。

app.pyのmodel postのdef __repr__(self):をコメントアウトした(これが生きていると,returnでstring型しか返らないらしい)。

公式

>>> from sqlalchemy.orm import joinedload  
>>> query = Category.query.options(joinedload('posts'))  
>>> for category in query:  
...     print category, category.posts  
<Category u'Python'> [<Post u'Hello Python!'>, <Post u'Snakes'>]  

insert

from app import Post,Category,db  

cat = Category(name='ruby')  
aaa = Post(title="ruby",body="content",category=cat)  
db.session.add(aaa)  
db.session.commit()  

このような感じで,子であるpost側から,categoryを文字列で指定すると,categoryを新しく作って,insertすることができる。

公式のquickstart

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@mihiraTakashiの技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう