ページ

2013年9月9日月曜日

mongoengineでのmongo db操作

今まではSQLite、MySQLを使ってデータベース接続部分を作っていましたが、DBのスキーマを変更する機会が多いためmongodbを使う事にしました。

ちなみにスキーマをしっかり決めればいいじゃんと思われる方もいるかと思いますが、リーンスタートアップで言うMVP(Most Valuable Product)をささっと作ってそこからユーザ要望を聞き出してどんどん改善をしていくというケースでは使えると思っています。

pythonからSQLiteやMySQLを使うときはSQLiteをORMとして使っていましたが、SQLAlchemyがmongodbに対応していないため、mongoengineを使う事にしました。

今回はmongoengineの使い方をちょっと書きます。

まずはインストールですが、pipを使ってmongoengineをインストールします。
# pip install mongoengine
プログラムは以下の様に書きます。
from mongoengine import Document, SequenceField, StringField,connect

class Person(Document):
    id = SequenceField(primary_key=True)
    name = StringField()

if __name__ == '__main__':
    connect('testdb01', host='localhost', port=27017)
    person = Person()
    person.name = 'Test Person'
    person.save()

説明:mongoengineをつかってORMを書く場合は、Documentを継承するクラスを作成します。そしてメンバにフィールド(RDBの列に相当するもの)を設定します。実際にDBを操作する処理はメインの中にあります。
まずconnectメソッドを使ってmongodbに接続します。コネクションはmongoengineのフレームワークによって処理されます。そのため、同じプロセスの中からDBにコネクションをする場合は、一度connectしてしまえば、その後はコネクション処理を考慮しなくても大丈夫です。
connectしたあとは他のORMと同じようにORMのクラスをインスタンス化して、メンバ変数に値を設定して、保存してという流れになります。

今回示したプログラムでデータを保存するとmongodbには以下のようなデータが保存されます。

{ "_id" : 1, "name" : "Test Person"}

今回はidにprimary_keyを設定しているため、上記データ形式になりますが、primary_keyを使用していない場合は、primary_keyとしてObjectIdが自動的に生成されて設定されます。

{ "_id" : ObjectId("522dda6752a8cf0ffcc35560"), "name" : "Test Person" }

mongoengineはコネクション処理もフレームワーク側で処理してくれるし、ORMの書き方もSQLAlchemyに似ているのでかなり使いやすくておすすめです。

2013年3月20日水曜日

SQLAlchemy+SQLiteでのAuto Increment

SQLAlchemy+SQLiteでAutoIncrementを使うときは、単にPrimaryKeyに値を入れずにcommitすれば良い。


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

engine = create_engine('sqlite:///test.db', echo=True)
Base = declarative_base(bind=engine) 
 
class MyClass(Base):
    __tablename__ = 'my_table'
    id = Column(Integer, primary_key=True)
    type = Column(String(50))
    alt = Column("some_alt", Integer)

if __name__ == '__main__':

    Session = sessionmaker(bind=engine)
    session = Session()
    Base.metadata.create_all(engine)
 
    myclass = MyClass()
    myclass.type = "taiga"
    myclass.alt = 10
    
    session.add(myclass)
    session.commit()
上のプログラムではid(primary key)に何の値も入れずにcommitしているが、フレームワーク側でprimary keyをincrementしてくれる。

2012年11月30日金曜日

argparse

pythonをコマンドラインで実行する時にオプションの設定がしたい場合はargparseを使えば楽。
ちなみにargparseはpython2.6からデフォルトで入っている。

サンプルのプログラムはこんなかんじ

import argparse

 

if __name__ == '__main__':

    parser = argparse.ArgumentParser(description='do something')

    parser.add_argument('files', nargs='*')

    parser.add_argument('--host', nargs=1,required=True)

    parser.add_argument('--debug', action='store_true')

    args = parser.parse_args()



    if args.debug:

        print args.host[0]



        for file in args.files:

             print file

# python xxx.py a b c --host 192.168.1.1 --debug
<実行結果>
192.168.1.1
a
b
c

nargsでそのオプションにたいする引数の数を指定できる。
なので('--host',nargs=4,required=True)としてサーバを4台分指定するとかができる。
これをするとプログラムのでは中に定数として接続先サーバの情報をもたず引数で必要な情報を指定して処理を分けるといったことができるようになる。
結構便利!!

2012年6月13日水曜日

SQLAlchemyのORM


ORM
 - SQLAlchemyでORMを使うためにはbaseクラスを使う方法と、Tableクラスとmapperメソッドを使う方法がある。
  - Tableクラスとmapperメソッドを使う方法は古いやりかたらしい。一応やりかたは以下の通り

from sqlalchemy import Column, Integer, String, Table 
from sqlalchemy.schema import MetaData
from sqlalchemy import create_engine

engine = create_engine('sqlite:///:memory:', echo=True) # 接続先DBの設定

metadata = MetaData()

my_table = Table("my_table", metadata,
    Column('id', Integer, primary_key=True),
    Column('type', String(50)),
    Column("some_alt", Integer)
)

class MyClass(object):
    pass

mapper(MyClass, my_table, 
    properties={
        'type':my_table.c.type,
        'alt':my_table.c.some_alt
    })

metadata.create_all() # Table作成


  - Tableクラスとmapperメソッドを使ったORMをbaseクラスを使った方法に置き換えると以下のようになる。
    baseクラスを継承したクラスを作成すると、Metadataをメンバに持つクラスを作る事ができる。

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

engine = create_engine('sqlite:///:memory:', echo=True) # 接続先DBの設定
Base = declarative_base(bind=engine)

class MyClass(Base):
    __tablename__ = 'my_table'
    id = Column(Integer, primary_key=True)
    type = Column(String(50))
    alt = Column("some_alt", Integer)
 
Base.metadata.create_all(engine) # Table作成

  - またDBへの挿入、更新、参照などをする場合はDB接続のためのSessionオブジェクトとORMを使ってDBの操作を行う。

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base(bind=engine)
Session = sessionmaker(bind=engine)
session = Session()

class MyClass(Base):
    __tablename__ = 'my_table'
    id = Column(Integer, primary_key=True)
    type = Column(String(50))
    alt = Column("some_alt", Integer)

Base.metadata.create_all(engine)

myclass = MyClass()
myclass.id = 0
myclass.type = "myclass"
myclass.alt = 10

session.add(myclass) # insertやupdateをするためのデータを持ったORMオブジェクトをセッションに追加
session.commit() # セッション中に存在するORMオブジェクトを使ってinsertもしくはupdateする

2011年4月10日日曜日

Slim3のservlet mapping

この概要は表示できません。投稿を閲覧するには ここをクリック してください。