銀月の符号

Python 使い見習いの日記・雑記

SQLAlchemy で Firebird その3

クエリー関連(ORM 版)

詳しくは Object Relational Tutorial に載っている。

とりあえず DB 設定、テーブル設計、セッションの作成を。

from sqlalchemy import create_engine
from sqlalchemy import Column
from sqlalchemy import Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Person(Base):
    __tablename__ = 'person'

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String(128))

db_path = 'firebird+kinterbasdb://user:password@host/dbalias'
engine = create_engine(db_path)
Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

DB 設定できた、テーブルできた、セッションできた。準備 OK 。

INSERT

セッションの add メソッドに作成したオブジェクトを渡す。

person1 = Person()
person1.id = 1
person1.name = u'fgshun'

session.add(person1)
session.commit()
UPDATE

INSERT となんらかわらず。

person1.name = u'fgshun'
session.add(person1)
session.commit()

複数を対象とする UPDATE を行うには後述の Query オブジェクトの update メソッドを用いる。

DELETE

セッションの delete メソッドにオブジェクトを渡せばよい。

session.delete(person1)
session.commit()
SELECT

セッションの query メソッドを呼び出すと Query オブジェクトができる。これの all を呼び出すと、取り出したレコードすべてを含むリストが得られる。

for p in session.query(Person).all():
    print p.id, p.name

all のほかに first, one というのもなる。 first は最初の 1 レコードだけを返す。 1 レコードもなければ None を返す。 one は 1 レコードだけが得られたかどうかチェックし、ダメならば例外送出。あっていればこの 1 レコードを返す。これらの返すものはリストではない。

p = session.query(Person).first()
p = session.query(Person).one()
WHERE

Query オブジェクトはさまざまなメソッドをもつ。まずは filter_by 。 WHERE spam == ham のようなものを書くときに使える。また、多くの Query メソッドは Query オブジェクトを返すので、続けて all などの他の Query メソッドを呼ぶことができる。つまり、こうなる。

for p in session.query(Person).filter_by(id = 1).all():
    print p.id, p.name

次は filter 。

for p in session.query(Person).filter(Person.id == 1).all():
    print p.id, p.name

== 以外の演算子も用いることができる分、こちらのほうがいろいろな操作が可能。 ==, !=, >, <, >=, <= 。

for p in session.query(Person).filter(Person.id > 3).all():
    print p.id, p.name
AND,OR
from sqlalchemy import and_, or_
session.query(Person).filter(and_(Person.id == 1, Person.name == u'シュン')).all()
session.query(Person).filter(or_(Person.id == 1, Person.name == u'シュン')).all()
LIKE
for p in session.query(Person).filter(Person.name.like('%a%')).all():
    print p.id, p.name
IN
for p in session.query(Person).filter(
        Person.name.in_(['a', 'b'])).all():
    print p.id, p.name

NOT IN を行うには ~ を用いる。

for p in session.query(Person).filter(
        ~Person.name.in_(['a', 'b'])).all():
    print p.id, p.name
IS NULL
for p in session.query(Person).filter(Person.name == None).all():
    print p.id, p.name

IS NOT NULL を行うには != None とする。

COUNT
session.query(Person).count()
GROUP BY
print session.query(func.count(Person.name), Person.name).group_by(Person.name).all()
LIMIT,OFFSET

Python スライスといっしょ。

# limit 1
session.query(Person.id, Person.name).order_by(Person.id)[:1]
# offset 1
session.query(Person.id, Person.name).order_by(Person.id)[1:]