PythonプログラムとFlaskフレームの中でSQLAlchemyの教程を使います。
22492 ワード
各地を渡り歩く
いつか、プログラマーはSQLを恐れて、慎重にsqlを書いています。心の中ではいつもパニックが避けられません。もしsql文を間違えたら、データベースを壊したらどうすればいいですか?また、いくつかのデータを取得するために、内外左右の接続、関数格納プロセスなどがあります。疑いのないことです。これらを理解しないと、どうしてもねじれてしまいます。いつか穴に飛び込み、「毎日」と叫んで答えないかもしれません。
ORMの出現によって、SQLを恐れた開発者は、穴の中にはっていくロープを見ました。空はそんなに暗くないようです。少なくとも暗くて、私たちも目があります。名前の通り、ORMオブジェクト関係のマッピングは、簡単に言えば、データベースの一つずつのテーブルをプログラミング言語のクラスにマッピングすることです。
pythonには有名なORMの枠组みがたくさんあります。大名トップのSQLAlchemyはpythonの世界では譲れないORMの枠组みです。江湖の中でpeeweee、strom、pyorm、SQLObjectはそれぞれ乱れていますが、結局はSQLAlchemyが群雄を傲視しています。
SQLAlchemy概要
SQLAlchemyは二つの部分に分けられています。一つはORMに対するオブジェクトマッピング、もう一つはコアSQL exprestionです。最初はよく分かりました。純粋なORMです。これはORMではなく、DBAPIのパッケージです。もちろん、sqlを直接書くのを避けて、sql表現を通しています。SQLAlchemyを使うと、三つの方法に分けられます。 sql expressionを使ってSQLAlchemyの方法でsql表現を書きます。簡単なのはsql を書きます。.raw sqlを使って直接sqlを書きます。 ORMを使って直接書きません。
本稿ではまずSQLAlchemyのsql exprestion部分の使い方を検討する。主に公式のSQL Expression Language Tutorialに従って紹介します。
なぜsql exprestionを勉強しますか?直接ORMに行きません。後ろの二つはormの基礎ですから。また、ormを使用しないで、後の2つは作業をうまく行うことができ、コードの可読性がより良いです。純粋にSQLAlchemyをdbapiとして使っています。まずSQLAlchemy内にデータベース接続池を建設し、接続操作に関する煩わしい処理を解決しました。次に、便利で強力なロゴ機能を提供します。最後に、複雑な検索文は、単純なORMでは実現しにくいです。
実戦
データベースを接続
まずsqlalchemyライブラリを導入して、データベース接続を確立します。ここでmysqlを使います。createを通じて(u)engine方法で行う
データベースの種類://ユーザー名:パスワード(パスワードがないと空です。書かない)@データベースのホストアドレス/データベース名?コーディング
echo=Trueはコンソールのロゴを便利にするためにsql情報を出力します。デフォルトはFalseです。
このengineオブジェクトによって直接executeで照会することができ、例えばengine.execute(「SELECT*FROM user」)は、engineを介してクエリーに接続されているものを取得することもでき、例えばconn=engine.co nnect()は、conn.execute()方法によって照会することができる。両者の違いは何ですか?
engineのexecuteを直接使用してsqlを実行する方式をconnnectionless実行といいます。
engine.co nnectによってconnを取得し、connを通じてsqlを実行することをconnectionといいます。
主な違いはtranspationモードを使うかどうかです。transactionに関係しないなら、2つの方法は同じです。公式サイトでは後者を推奨しています。
定義テーブル
データテーブルを定義してこそ、sql表式の操作ができます。結局sql表式の表の確定は、sqlalchemyによって制定されました。もしデータベースにデータテーブルが存在したら、まだ定義が必要ですか?もちろん、ここはマッピング関係です。指定しないと、クエリー表現はそのテーブルに付加された操作であることが分かりません。もちろん定義するときは、テーブル名とフィールド名に注意してください。コードとデータは一致していなければなりません。定義したら、データテーブルが作成されます。作成したコードを再実行したら、データベースは作成されません。
データテーブルと接続先があれば、データベース操作に対応するのが簡単です。
検索方法はとても柔軟で、sqlalchemy.sql以下のselect方法を使うことが多いです。
ここの接続とは、条件照会時の論理演算子の接続、すなわち、and orとnotのことです。
担当のsql文に出会ったときは、sqlalchemy.sqlの下のtext関数を使うことができます。文字列のsql文を包装してexecute実行に必要なsqlオブジェクトにコンパイルします。例えば:、
joinとoutejoinの二つの方法があります。joinには二つのパラメータがあります。一つ目はジョンの表、二つ目はonの条件です。jingの後はselect(u)に協力しなければなりません。from方法:
並べ替えにはorder_を使用しますbyメソッドは、グループ化はグループ化されます。by、改ページはもちろんlimitとoffsetの二つの方法で協力します。
前は全部いくつかの検索です。更新と挿入の方法は似ています。全部表の下の方法です。違いは、udateがもう一つのwhere方法を使ってフィルタリングを選択します。
削除は比較的簡単で、delete方法を呼び出してもいいです。whereフィルタをかけないと、すべてのデータは削除されます。しかし、dropが表に落ちないので、データテーブルが空になったのと同じです。
SQLAlchemyはすでにpython世界の中のormの標準になりました。flashkは軽いウェブフレームで、ormを自由に使えます。flak-sqlalchemyはflashkのために指定されたプラグインです。
flashk-sqlalchemyをインストールします。
データパッケージの作成はsqlalchemyアプリを使っています。テーブルが既に存在している場合は無視します。存在しない場合は、新規に作成します。
関係データベースで一番重要なのは関係です。通常の関係は1対1(例えば、無限級欄)、1対複数(文章と欄)、多対多(文章とラベル)に分けられます。
one to may:
私たちはCategory(欄)とPost(文章)を定義します。両者は一対の多い関係で、一つの欄には多くの文章があり、一つの文章は一つの欄に属しています。
複数のペアの複数の関係については、2つのモデルのIDを定義する他のテーブル、例えばPostとTagの間に複数のペアがあり、Post_を定義する必要がある。Tagの時計
いつか、プログラマーはSQLを恐れて、慎重にsqlを書いています。心の中ではいつもパニックが避けられません。もしsql文を間違えたら、データベースを壊したらどうすればいいですか?また、いくつかのデータを取得するために、内外左右の接続、関数格納プロセスなどがあります。疑いのないことです。これらを理解しないと、どうしてもねじれてしまいます。いつか穴に飛び込み、「毎日」と叫んで答えないかもしれません。
ORMの出現によって、SQLを恐れた開発者は、穴の中にはっていくロープを見ました。空はそんなに暗くないようです。少なくとも暗くて、私たちも目があります。名前の通り、ORMオブジェクト関係のマッピングは、簡単に言えば、データベースの一つずつのテーブルをプログラミング言語のクラスにマッピングすることです。
pythonには有名なORMの枠组みがたくさんあります。大名トップのSQLAlchemyはpythonの世界では譲れないORMの枠组みです。江湖の中でpeeweee、strom、pyorm、SQLObjectはそれぞれ乱れていますが、結局はSQLAlchemyが群雄を傲視しています。
SQLAlchemy概要
SQLAlchemyは二つの部分に分けられています。一つはORMに対するオブジェクトマッピング、もう一つはコアSQL exprestionです。最初はよく分かりました。純粋なORMです。これはORMではなく、DBAPIのパッケージです。もちろん、sqlを直接書くのを避けて、sql表現を通しています。SQLAlchemyを使うと、三つの方法に分けられます。
本稿ではまずSQLAlchemyのsql exprestion部分の使い方を検討する。主に公式のSQL Expression Language Tutorialに従って紹介します。
なぜsql exprestionを勉強しますか?直接ORMに行きません。後ろの二つはormの基礎ですから。また、ormを使用しないで、後の2つは作業をうまく行うことができ、コードの可読性がより良いです。純粋にSQLAlchemyをdbapiとして使っています。まずSQLAlchemy内にデータベース接続池を建設し、接続操作に関する煩わしい処理を解決しました。次に、便利で強力なロゴ機能を提供します。最後に、複雑な検索文は、単純なORMでは実現しにくいです。
実戦
データベースを接続
まずsqlalchemyライブラリを導入して、データベース接続を確立します。ここでmysqlを使います。createを通じて(u)engine方法で行う
from sqlalchemy import create_engine
engine = create_engine("mysql://root:@localhost:3306/webpy?charset=utf8",encoding="utf-8", echo=True)
クリアードengineメソッドはデータベース接続を行い、dbオブジェクトを返します。中のパラメータ表示データベースの種類://ユーザー名:パスワード(パスワードがないと空です。書かない)@データベースのホストアドレス/データベース名?コーディング
echo=Trueはコンソールのロゴを便利にするためにsql情報を出力します。デフォルトはFalseです。
このengineオブジェクトによって直接executeで照会することができ、例えばengine.execute(「SELECT*FROM user」)は、engineを介してクエリーに接続されているものを取得することもでき、例えばconn=engine.co nnect()は、conn.execute()方法によって照会することができる。両者の違いは何ですか?
engineのexecuteを直接使用してsqlを実行する方式をconnnectionless実行といいます。
engine.co nnectによってconnを取得し、connを通じてsqlを実行することをconnectionといいます。
主な違いはtranspationモードを使うかどうかです。transactionに関係しないなら、2つの方法は同じです。公式サイトでは後者を推奨しています。
定義テーブル
データテーブルを定義してこそ、sql表式の操作ができます。結局sql表式の表の確定は、sqlalchemyによって制定されました。もしデータベースにデータテーブルが存在したら、まだ定義が必要ですか?もちろん、ここはマッピング関係です。指定しないと、クエリー表現はそのテーブルに付加された操作であることが分かりません。もちろん定義するときは、テーブル名とフィールド名に注意してください。コードとデータは一致していなければなりません。定義したら、データテーブルが作成されます。作成したコードを再実行したら、データベースは作成されません。
# -*- coding: utf-8 -*-
__author__ = 'ghost'
from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
#
engine = create_engine("mysql://root:@localhost:3306/webpy?charset=utf8",encoding="utf-8", echo=True)
#
metadata = MetaData()
#
user = Table('user', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(20)),
Column('fullname', String(40)),
)
address = Table('address', metadata,
Column('id', Integer, primary_key=True),
Column('user_id', None, ForeignKey('user.id')),
Column('email', String(60), nullable=False)
)
# , ,
metadata.create_all(engine)
#
conn = engine.connect()
インサートデータテーブルと接続先があれば、データベース操作に対応するのが簡単です。
>>> i = user.insert() #
>>> i
<sqlalchemy.sql.dml.Insert object at 0x0000000002637748>
>>> print i # sql
INSERT INTO "user" (id, name, fullname) VALUES (:id, :name, :fullname)
>>> u = dict(name='jack', fullname='jack Jone')
>>> r = conn.execute(i, **u) # , , , ,
>>> r
<sqlalchemy.engine.result.ResultProxy object at 0x0000000002EF9390>
>>> r.inserted_primary_key # id
[4L]
>>> addresses
[{'user_id': 1, 'email': '[email protected]'}, {'user_id': 1, 'email': '[email protected]'}, {'user_id': 2, 'email': '[email protected]'}, {'user_id': 2, 'email': '[email protected]'}]
>>> i = address.insert()
>>> r = conn.execute(i, addresses) #
>>> r
<sqlalchemy.engine.result.ResultProxy object at 0x0000000002EB5080>
>>> r.rowcount #
4L
>>> i = user.insert().values(name='tom', fullname='tom Jim')
>>> i.compile()
<sqlalchemy.sql.compiler.SQLCompiler object at 0x0000000002F6F390>
>>> print i.compile()
INSERT INTO "user" (name, fullname) VALUES (:name, :fullname)
>>> print i.compile().params
{'fullname': 'tom Jim', 'name': 'tom'}
>>> r = conn.execute(i)
>>> r.rowcount
1L
selectを調べる検索方法はとても柔軟で、sqlalchemy.sql以下のselect方法を使うことが多いです。
>>> s = select([user]) # user
>>> s
<sqlalchemy.sql.selectable.Select at 0x25a7748; Select object>
>>> print s
SELECT "user".id, "user".name, "user".fullname
FROM "user"
ユーザー定義のフィールドを検索する必要がある場合は、例えば、userのcloumnオブジェクトを使用します。
>>> user.c # user column
<sqlalchemy.sql.base.ImmutableColumnCollection object at 0x0000000002E804A8>
>>> print user.c
['user.id', 'user.name', 'user.fullname']
>>> s = select([user.c.name,user.c.fullname])
>>> r = conn.execute(s)
>>> r
<sqlalchemy.engine.result.ResultProxy object at 0x00000000025A7748>
>>> r.rowcount #
5L
>>> ru = r.fetchall()
>>> ru
[(u'hello', u'hello world'), (u'Jack', u'Jack Jone'), (u'Jack', u'Jack Jone'), (u'jack', u'jack Jone'), (u'tom', u'tom Jim')]
>>> r
<sqlalchemy.engine.result.ResultProxy object at 0x00000000025A7748>
>>> r.closed # r.fetchall() , ResultProxy
True
二つの表を同時に調べます。
>>> s = select([user.c.name, address.c.user_id]).where(user.c.id==address.c.user_id) #
>>> s
<sqlalchemy.sql.selectable.Select at 0x2f03390; Select object>
>>> print s
SELECT "user".name, address.user_id
FROM "user", address
WHERE "user".id = address.user_id
オペレータ
>>> print user.c.id == address.c.user_id #
"user".id = address.user_id
>>> print user.c.id == 7
"user".id = :id_1 # sql
>>> print user.c.id != 7
"user".id != :id_1
>>> print user.c.id > 7
"user".id > :id_1
>>> print user.c.id == None
"user".id IS NULL
>>> print user.c.id + address.c.id # +
"user".id + address.id
>>> print user.c.name + address.c.email # ||
"user".name || address.email
操作接続ここの接続とは、条件照会時の論理演算子の接続、すなわち、and orとnotのことです。
>>> print and_(
user.c.name.like('j%'),
user.c.id == address.c.user_id,
or_(
address.c.email == '[email protected]',
address.c.email == '[email protected]'
),
not_(user.c.id>5))
"user".name LIKE :name_1 AND "user".id = address.user_id AND (address.email = :email_1 OR address.email = :email_2) AND "user".id <= :id_1
>>>
得られた結果はコンパイルされたsql文のセグメントです。
>>> se_sql = [(user.c.fullname +", " + address.c.email).label('title')]
>>> wh_sql = and_(
user.c.id == address.c.user_id,
user.c.name.between('m', 'z'),
or_(
address.c.email.like('%@aol.com'),
address.c.email.like('%@msn.com')
)
)
>>> print wh_sql
"user".id = address.user_id AND "user".name BETWEEN :name_1 AND :name_2 AND (address.email LIKE :email_1 OR address.email LIKE :email_2)
>>> s = select(se_sql).where(wh_sql)
>>> print s
SELECT "user".fullname || :fullname_1 || address.email AS title
FROM "user", address
WHERE "user".id = address.user_id AND "user".name BETWEEN :name_1 AND :name_2 AND (address.email LIKE :email_1 OR address.email LIKE :email_2)
>>> r = conn.execute(s)
>>> r.fetchall()
raw sql方式を使う担当のsql文に出会ったときは、sqlalchemy.sqlの下のtext関数を使うことができます。文字列のsql文を包装してexecute実行に必要なsqlオブジェクトにコンパイルします。例えば:、
>>> text_sql = "SELECT id, name, fullname FROM user WHERE id=:id" # sql , ( :value)
>>> s = text(text_sql)
>>> print s
SELECT id, name, fullname FROM user WHERE id=:id
>>> s
<sqlalchemy.sql.elements.TextClause object at 0x0000000002587668>
>>> conn.execute(s, id=3).fetchall() # id=3 :id
[(3L, u'Jack', u'Jack Jone')]
ジョインを接続joinとoutejoinの二つの方法があります。joinには二つのパラメータがあります。一つ目はジョンの表、二つ目はonの条件です。jingの後はselect(u)に協力しなければなりません。from方法:
>>> print user.join(address)
"user" JOIN address ON "user".id = address.user_id # , join on
>>> print user.join(address, address.c.user_id==user.c.id) # on
"user" JOIN address ON address.user_id = "user".id
>>> s = select([user.c.name, address.c.email]).select_from(user.join(address, user.c.id==address.c.user_id)) # jion sql select_from
>>> s
<sqlalchemy.sql.selectable.Select at 0x2eb63c8; Select object>
>>> print s
SELECT "user".name, address.email
FROM "user" JOIN address ON "user".id = address.user_id
>>> conn.execute(s).fetchall()
[(u'hello', u'[email protected]'), (u'hello', u'[email protected]'), (u'hello', u'[email protected]'), (u'hello', u'[email protected]'), (u'Jack', u'[email protected]'), (u'Jack', u'[email protected]'), (u'Jack', u'[email protected]'), (u'Jack', u'[email protected]')]
グループを並べ替える並べ替えにはorder_を使用しますbyメソッドは、グループ化はグループ化されます。by、改ページはもちろんlimitとoffsetの二つの方法で協力します。
>>> s = select([user.c.name]).order_by(user.c.name) # order_by
>>> print s
SELECT "user".name
FROM "user" ORDER BY "user".name
>>> s = select([user]).order_by(user.c.name.desc())
>>> print s
SELECT "user".id, "user".name, "user".fullname
FROM "user" ORDER BY "user".name DESC
>>> s = select([user]).group_by(user.c.name) # group_by
>>> print s
SELECT "user".id, "user".name, "user".fullname
FROM "user" GROUP BY "user".name
>>> s = select([user]).order_by(user.c.name.desc()).limit(1).offset(3) # limit(1).offset(3)
>>> print s
SELECT "user".id, "user".name, "user".fullname
FROM "user" ORDER BY "user".name DESC
LIMIT :param_1 OFFSET :param_2
[(4L, u'jack', u'jack Jone')]
アップデート前は全部いくつかの検索です。更新と挿入の方法は似ています。全部表の下の方法です。違いは、udateがもう一つのwhere方法を使ってフィルタリングを選択します。
>>> s = user.update()
>>> print s
UPDATE "user" SET id=:id, name=:name, fullname=:fullname
>>> s = user.update().values(fullname=user.c.name) # values
>>> print s
UPDATE "user" SET fullname="user".name
>>> s = user.update().where(user.c.name == 'jack').values(name='ed') # where
>>> print s
UPDATE "user" SET name=:name WHERE "user".name = :name_1
>>> r = conn.execute(s)
>>> print r.rowcount #
3
もう一つの高級な使い方があります。一つの命令で複数の記録の更新を行います。
>>> s = user.update().where(user.c.name==bindparam('oldname')).values(name=bindparam('newname')) # oldname ,newname
>>> print s
UPDATE "user" SET name=:newname WHERE "user".name = :oldname
>>> u = [{'oldname':'hello', 'newname':'edd'},
{'oldname':'ed', 'newname':'mary'},
{'oldname':'tom', 'newname':'jake'}]
>>> r = conn.execute(s, u)
>>> r.rowcount
5L
deleteを削除削除は比較的簡単で、delete方法を呼び出してもいいです。whereフィルタをかけないと、すべてのデータは削除されます。しかし、dropが表に落ちないので、データテーブルが空になったのと同じです。
>>> r = conn.execute(address.delete()) #
>>> print r
<sqlalchemy.engine.result.ResultProxy object at 0x0000000002EAF550>
>>> r.rowcount
8L
>>> r = conn.execute(users.delete().where(users.c.name > 'm')) #
>>> r.rowcount
3L
flak-sqlalchemySQLAlchemyはすでにpython世界の中のormの標準になりました。flashkは軽いウェブフレームで、ormを自由に使えます。flak-sqlalchemyはflashkのために指定されたプラグインです。
flashk-sqlalchemyをインストールします。
pip install flask-sqlalchemy
初期化sqlalchemy
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
# dialect+driver://username:password@host:port/database?charset=utf8
# sqlalchemy :// : @ : / ?
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:@localhost:3306/sqlalchemy?charset=utf8'
#
db = SQLAlchemy(app)
定義モデル
class User(db.Model):
""" , model
"""
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
def save(self):
db.session.add(self)
db.session.commit()
データテーブルの作成データパッケージの作成はsqlalchemyアプリを使っています。テーブルが既に存在している場合は無視します。存在しない場合は、新規に作成します。
>>> from yourapp import db, User
>>> u = User(username='admin', email='[email protected]') #
>>> db.session.add(u) # session
>>> db.session.commit() #
>>> users = User.query.all() #
中国語を挿入するには、unicode文字列を挿入しなければなりません。
>>> u = User(username=u' ', email='[email protected]')
>>> u.save()
関係を定義関係データベースで一番重要なのは関係です。通常の関係は1対1(例えば、無限級欄)、1対複数(文章と欄)、多対多(文章とラベル)に分けられます。
one to may:
私たちはCategory(欄)とPost(文章)を定義します。両者は一対の多い関係で、一つの欄には多くの文章があり、一つの文章は一つの欄に属しています。
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
def __init__(self, name):
self.name = name
def __repr__(self):
return '<Category %r>' % self.name
class Post(db.Model):
""" , id,title,body,pub_date,category_id
"""
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(80))
body = db.Column(db.Text)
pub_date = db.Column(db.String(20))
#
category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
# ,
# backref , Category backref(post_set) Post
category = db.relationship('Category', backref=db.backref('post_set', lazy='dynamic'))
def __init__(self, title, body, category, pub_date=None):
self.title = title
self.body = body
if pub_date is None:
pub_date = time.time()
self.pub_date = pub_date
self.category = category
def __repr__(self):
return '<Post %r>' % self.title
def save(self):
db.session.add(self)
db.session.commit()
検索はどうやって使いますか?
>>> c = Category(name='Python')
>>> c
<Category 'Python'>
>>> c.post_set
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003B58F60>
>>> c.post_set.all()
[]
>>> p = Post(title='hello python', body='python is cool', category=c)
>>> p.save()
>>> c.post_set
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003B73710>
>>> c.post_set.all() #
[<Post u'hello python'>]
>>> p
<Post u'hello python'>
>>> p.category
<Category u'Python'>
# category_id
>>> p = Post(title='hello flask', body='flask is cool', category_id=1)
>>> p.save()
many to many(コメントはすでに指摘されています。このようなやり方は関連して削除することができません。簡単な本は線のフォーマットを削除していません。多く例に対して廃棄します。ここで注意してください。誤解されないように。)複数のペアの複数の関係については、2つのモデルのIDを定義する他のテーブル、例えばPostとTagの間に複数のペアがあり、Post_を定義する必要がある。Tagの時計
post_tag = db.Table('post_tag',
db.Column('post_id', db.Integer, db.ForeignKey('post.id')),
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'))
)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
# ...
# ,tag post_set post
tags = db.relationship('Tag', secondary=post_tag,
backref=db.backref('post_set', lazy='dynamic'))
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(10), unique=True)
#
posts = db.relationship('Post', secondary=post_tag,
backref=db.backref('tag_set', lazy='dynamic'))
def __init__(self, content):
self.content = content
def save(self):
db.session.add(self)
db.session.commit()
クエリー:
>>> tag_list = []
>>> tags = ['python', 'flask', 'ruby', 'rails']
>>> for tag in tags:
t = Tag(tag)
tag_list.append(t)
>>> tag_list
[<f_sqlalchemy.Tag object at 0x0000000003B7CF28>, <f_sqlalchemy.Tag object at 0x0000000003B7CF98>, <f_sqlalchemy.Tag object at 0x0000000003B7CEB8>, <f_sqlalchemy.Tag object at 0x0000000003B7CE80>]
>>> p
<Post u'hello python'>
>>> p.tags
[]
>>> p.tags = tag_list #
>>> p.save()
>>> p.tags
[<f_sqlalchemy.Tag object at 0x0000000003B7CF28>, <f_sqlalchemy.Tag object at 0x0000000003B7CF98>, <f_sqlalchemy.Tag object at 0x0000000003B7CEB8>, <f_sqlalchemy.Tag object at 0x0000000003B7CE80>]
>>> p.tag_set #
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003B7C080>
>>> p.tag_set.all()
[<f_sqlalchemy.Tag object at 0x0000000003B7CF28>, <f_sqlalchemy.Tag object at 0x0000000003B7CF98>, <f_sqlalchemy.Tag object at 0x0000000003B7CEB8>, <f_sqlalchemy.Tag object at 0x0000000003B7CE80>]
>>> t = Tag.query.all()[1]
>>> t
<f_sqlalchemy.Tag object at 0x0000000003B7CF28>
>>> t.content
u'python'
>>> t.posts
[<Post u'hello python'>]
>>> t.post_set
<sqlalchemy.orm.dynamic.AppenderBaseQuery object at 0x0000000003B7C358>
>>> t.post_set.all()
[<Post u'hello python'>]
self one to one
自分の一対一もよく使う需要です。例えば、無限の等級付けの欄です。
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50))
# id
pid = db.Column(db.Integer, db.ForeignKey('category.id'))
#
pcategory = db.relationship('Category', uselist=False, remote_side=[id], backref=db.backref('scategory', uselist=False))
def __init__(self, name, pcategory=None):
self.name = name
self.pcategory = pcategory
def __repr__(self):
return '<Category %r>' % self.name
def save(self):
db.session.add(self)
db.session.commit()
クエリー:
>>> p = Category('Python')
>>> p
<Category 'Python'>
>>> p.pid
>>> p.pcategory #
>>> p.scategory #
>>> f = Category('Flask', p)
>>> f.save()
>>> f
<Category u'Flask'>
>>> f.pid
1L
>>> f.pcategory #
<Category u'Python'>
>>> f.scategory #
>>> p.scategory #
<Category u'Flask'>
flash-sqlalchemy定義modelsの簡単な応用についてはこれだけです。もっと多い技術はどうやって調べますか?