2009/06/19

autoload declarative sqlalchemy

既存 db を Python で読みたい!

SQLAlchemy が正解だと教わったり教わったりで基本はこんな感じらしい
from sqlalchemy import (
create_engine,
MetaData, Table, Column,
Integer, VARCHAR
)
from sqlalchemy.orm import mapper

url = 'mysql://username:password@server/db_name'
engine = create_engine(url, echo=True)
metadata = MetaData()

parent_table = Table('parent_tb', metadata,
Column('id', Integer, primary_key=True),
Column('name', VARCHAR(256)),
)

class Parent(object):
pass

mapper(Parent, parent_table)

Session = sessionmaker(bind=engine)
session = Session()
既存 db から写経で Table 用意して
Class 用意して mapper してあげるの

でも Table とか作るの面倒じゃない? という人には
from sqlalchemy import (
create_engine,
Column,
Integer, VARCHAR
)
from sqlalchemy.ext.declarative import declarative_base

url = 'mysql://username:password@server/db_name'
engine = create_engine(url, echo=True)
Base = declarative_base()

class Parent(Base):
__tablename__ = 'parent_tb'

id = Column(Integer, primary_key=True),
name = Column(VARCHAR(256))

Session = sessionmaker(bind=engine)
session = Session()
__tablename__ とかで色々 Table のこと渡すのね
まぁ、ちょっと楽になったかしら

でも既存の db の Column で登録メンドクサイよ!!という場合
autoload というのを使いなさいと言われ調べたりもした結果
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base

url = 'mysql://username:password@server/db_name'
engine = create_engine(url, echo=True)
Base = declarative_base(engine)

class Parent(Base):
__tablename__ = 'parent_tb'
__table_args__ = {'autoload':True}

class Child(Base):
__tablename__ = 'child_tb'
__table_args__ = {'autoload':True}
parent = relation('Parent', backref='children')

Session = sessionmaker(bind=engine)
session = Session()
こんな感じになりました
いきなり Child できてるけど
declarative_base に engine 食わせてるのは
本当は MetaData に engine か connection が紐付いているべきらしく
class の中で __???__ とかで定義してもいいんだろうけれども
まぁとりあえず動いたし今んとこ engine 1 つだからいいかなと

__table_args__ 使ったけど __autoload__ とかもあるらしいので
詳しいことはちゃんと Table のこと知ってあげないとダメね

何か、一段落して、感動しました
SQLAlchemy 素敵だね!!

2009/06/18

python import 改行

explicit たれ、なんかそんなことどっかで言われた気がしたので
Python っつったら import んとき * 使っちゃいけないんじゃないかと思い
だらだら import してみたら大変なことになってしまいました
もぉ嫌

で、そういえば import とかでも改行しても良かったよなと思い検索
Pythonのコードをきれいに書くためのTips — TRIVIAL TECHNOLOGIES 2.0
うへぇ
import とかもぉそういうレベルではなく
そもそも Python のコードとは美しくあるべきだと叱って頂いた気分です
今後気をつけます

で、問題? の import は、例えばまぁ
from sqlalchemy import (
create_engine, MetaData, Table, Column,
VARCHAR, Integer, SmallInteger, DateTime, ForeignKey
)
ってできるみたいなんですが
from sqlalchemy import *
のが読み易いかなぁ...

>>> 'abc' 'bcd'
'abcbcd'
はー、知らんかった

"jQuery.get"

jQuery入門を教えて頂いたので読みました
第5章 「非同期通信でデータを読み込む」でちょっとつまづきまして
$(function(){
var httpObj = jQuery.get("./news.txt",null, function(){
alert(httpObj.responseText);
});
});
httpObj の中で httpObj 呼ぶの? 何してるのこれ??
検索しました

jQuery.get( url, data, callback ) - jQuery 1.3.2 日本語リファレンス
あー、そうよねぇ
jQuery object は作成されておいて
通信が成功したら自分自信の内容を alert にわたすのねぇ
少しは考えれば直ぐ分かりそうなものを検索してしまったという
悪い例になってしまいました

2009/06/15

modelform "def clean"

Django で日付の前後関係で validation したいなと思いました。
validation がどこで行われてるのかすら頭になかったんですが
適当に検索すると clean_???? (???? は form field の名前ね) とか clean とかで
色々されてることが分かりました。
で、複数の field を跨ぐ validation は clean を override するらしい。

サンプルがどっかにあるに違いないと思い
modelform を使ってるところで clean を override してるページを検索すると
[django-ja:662] ModelFormにおけるユニークフィールドのバリデーション
http://groups.google.com/group/django-ja/browse_thread/thread/74fcda259ded1cd0 の方が最初に hit
おぉ、真に
    def clean(self):
cleaned = super(CompanyForm, self).clean()
date_from = cleaned.get('valid_from')
date_to = cleaned.get('valid_to')
if date_from is not None and date_to is not None:
if date_to < date_from:
raise forms.ValidationError(u'有効期間の終了日が開始日よりも前の日付です。')
return cleaned
override していらっしゃる。
ので、真似っこしたら上手くいきました。

あぁ、Creating forms from models を見るとちゃんと
class MyModelFormSet(BaseModelFormSet):
def clean(self):
super(MyModelFormSet, self).clean()
# example custom validation across forms in the formset:
for form in self.forms:
# your custom formset validation
書いてあるなぁ、ちょっと違うけど

ADMIN_MEDIA_PREFIX MEDIA_ROOT

Django で日付入れるところでカレンダーを出したいと思いました。
何故お前は jQuery UI を使わないのだ (いや使うべきだ) 的なお言葉頂いたので、
是非とも使おうと思って流石にファイルは手元に置くべきかなと。
で、そんなときは media とかいうのを使うんだってとこまでは分かってました。

で、settings.py を見ると MEDIA_ROOT とか MEDIA_URL とかあって、あぁこれかと。
でもその下に ADMIN_MEDIA_PREFIX ってのもあるじゃないですか、使ってるし admin。
これは、/media/ は admin で使ってるから MEDIA_URL は避けるべき?
それとも Django は賢いからその辺何とかしてくれちゃうの??
ってやってみるとかドキュメント見るとかいう選択肢もあるでしょうが
ここはググるの一択なわけで。

[django-ja:376] Re: MEDIA_ROOT について
管理用のメディアファイルとサイト用のメディアファイルのurlが重複している際に起きているはずです。
なのでサイト用のメディアファイルのurlをsite_mediaなどにすれば解決します。

(r'^site_media/(?P.*)','django.views.static.serve',
dict(document_root=settings.MEDIA_ROOT)),
おぉ、同じだと問題があるらしい、これは避けねば。
つか、この検索語で何故最初にひっかかるのが just な答なのか分かりません。
Google 先生に気持ちが伝わったとしか思えません。
う〜ん、スピリチュアル。

良い子のみんなはちゃんと静的なファイルの提供方法も読もうね!!

2009/06/14

"mmc0: error -110 whilst initialising SD card" thinkpad

SD カードを読もうと思ってカードリーダを取り出しつつ
「そういえばこのノートには SD カードを挿す穴が付いてたじゃない」
と思い挿してみたんですが
mmc0: error -110 whilst initialising SD card
なんて言われて読まれる気配がありません

や、時代の進歩は遥か先を進んでいるはずと思い検索してみました
ちなみに Debian Lenny で kernel-image は特にいじってません
で、しっかり Ubuntu の bug report みたいなページが出てきて
https://bugs.launchpad.net/ubuntu/+bug/311781
The suggestion from https://bugs.launchpad.net/ubuntu/+source/linux-source-2.6.22/+bug/111089 works great.
なんて書いてあったから見にいってみて
# modprobe mmc_block
# modprobe tifm_sd
ってして抜き挿ししてみたらしっかり読めました

ちなみに
# lsmod
Module Size Used by
nls_utf8 1760 0
nls_cp437 5568 0
vfat 9184 0
fat 40896 1 vfat
nls_base 6820 4 nls_utf8,nls_cp437,vfat,fat
tifm_sd 8584 0
tifm_core 7548 1 tifm_sd
mmc_block 8932 0
usb_storage 77024 0
i915 25280 2
drm 65192 3 i915
こんな感じ

mmc_block だけでもいけた