2007-11-20
■[SQLAlchemy][Django]DjangoでSQLAlchemy
今日、Pyhton焼肉に行ったときに、id:soundkitchenさんから、DjangoでSQLAlchemyを使う方法について質問を受けたのですが、あとで見返してみても、以前書いたこと以上のことは、実際やっていません・・・
http://d.hatena.ne.jp/perezvon/20070926/1190823332
例えば、Djangoプロジェクト名をgumiと作り、そのプロジェクトが使う唯一のデータベース接続を表現するパッケージを、gumi/db.pyとして表現するとすると、
# -*- coding: utf-8 -*- from django.conf import settings from django.core import signals from django.dispatch import dispatcher import sqlalchemy from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.engine.url import URL __all__ = ['Session', 'metadata'] def create_engine(): url = URL(drivername=settings.DATABASE_ENGINE, database=settings.DATABASE_NAME, username=settings.DATABASE_USER, password=settings.DATABASE_PASSWORD, host=settings.DATABASE_HOST, port=settings.DATABASE_PORT or None, query = getattr(settings, 'DATABASE_OPTIONS', {}) ) options = getattr(settings, 'SQLALCHEMY_OPTIONS', {}) engine = sqlalchemy.create_engine(url, **options) return engine def end_request(signal, sender): Session.remove() dispatcher.connect(receiver=end_request, signal=signals.request_finished) metadata = sqlalchemy.MetaData() Session = scoped_session(sessionmaker(autoflush=True, transactional=True, bind=create_engine()))
ここで書いているコードが、まさにgu3.jpで動いている、一字一句と違わないSQLAlchemyの接続部分のコードです。
上のようなコードをgumi/db.pyとして定義した上で、モデルの部分で次のように、モデルを定義します。
from sqlalchemy import * from gumi.db import Session, metadata some_table = Table('some_table', metadata, Column('id', Integer, primary_key=True), Column('some_value', varchar(250), nullable=False), mysql_engine='InnoDB' )
gu3.jpのテーブル定義とモデル定義の部分は、実際には、次のようなコードのパターンになっています。
from sqlalchemy.orm import * from gumi.db import Session, metadata some_table = Table('some_table', metadata, Column('id', Integer, primary_key=True), Column('some_value', String(100), nullable=False, mysql_engine='InnoDB', ) class SomeObject(object): pass mapper(SomeObject, some_table)
ビューでは、次のようなコードでビュー関数として登録しています。
import django.newforms as forms from gumi.db import Session class SomeForm(forms.Form): # newformを明示的に定義します pass def some_action(req): if req.method != "POST": form = SomeForm() else: form = SomeForm(req.POST) if form.is_valid(): data = form.clean() obj = SomeObject() obj.some_param = data['a'] obj.another_param = data['b'] Session.save(obj) Session.commit() return HttpResponseRedirect('/') return render_to_response('some/template.html')
こういうコートの書き方にすることによって生じる不都合というものも認識していますが、「1アプリケーション1DB接続」という構成ならば、不都合は生じないはず(SQLAlchemy0.4以降ならばこうかくべき)という書き方です。
リンク元
- 40 http://www.ueblog.org/mediawiki/index.php?title=Django_SQLAlchemy
- 34 http://reader.livedoor.com/reader/
- 29 http://www.google.co.jp/search?hl=&q=django+sqlalchemy&sourceid=navclient-ff&rlz=1B3GGGL_jaJP346JP346&ie=UTF-8&aq=2&oq=django+sql
- 26 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&hs=hML&sa=X&oi=spell&resnum=0&ct=result&cd=1&q=email+Utils+python&spell=1
- 25 http://www.google.co.jp/search?q=django+sqlalchemy&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja-JP-mac:official&client=firefox-a
- 20 http://www.google.co.jp/search?q=django+sqlalchemy&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:ja:unofficial&client=firefox-a
- 20 http://www.google.co.jp/search?q=sqlalchemy&lr=lang_ja&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:ja:official&client=firefox-a
- 16 http://db2.jugem.cc/?eid=1364
- 14 http://translate.google.com/translate_p?hl=en&sl=ja&u=http://d.hatena.ne.jp/perezvon/20071120/1195577831&prev=/search?q=django+sqlalchemy+wsgi+sessionmaker&hl=en&rlz=1B3GGGL_enUS293US293&usg=ALkJrhgGDusreUwFvnbgZrd5MVhtSEbJ0Q
- 14 http://www.google.co.jp/url?sa=t&rct=j&q=django sqlalchemy&source=web&cd=1&ved=0CCAQFjAA&url=http://d.hatena.ne.jp/perezvon/20071120/1195577831&ei=7MOfTtjpDNHbiAL2s5hG&usg=AFQjCNFVaFxN7dV8nISJV0_K7tx2z1IZxQ&sig2=CVIe9W-fMiMz7usJ245g4g