Symfoware

Symfowareについての考察blog

SQLAlchemyの使い方1 単一テーブルのマッピングとデータの追加

SQLAlchemyの使い方を勉強してます。

チュートリアルに沿って進めてみます。
http://docs.sqlalchemy.org/en/latest/orm/tutorial.html



インストール



easy_installでインストールしました。


$ sudo easy_install sqlalchemy




データベースはPostgreSQLを使うことにしました。
接続には、Psycopg2を使用します。

PsycopgでPythonからPostgreSQL 9.3.2に接続する





Version Check



SQLAlchemyのバージョンを表示してみます。


  1. import sqlalchemy
  2. print(sqlalchemy.__version__)




「0.9.3」がインストールされていました。




Connecting



データベースへの接続設定です。

指定する接続文字列は事前に調べておきました。
Python SQLAlchemyの接続文字列一覧


psycopg2を使用するので、このようになります。


postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]




ユーザー:pgadmin
パスワード:password
サーバー:192.168.1.101
ポート:5432
データベース名:sample

を使用する場合はこんな感じ。


  1. import sqlalchemy
  2. url = 'postgresql+psycopg2://pgadmin:password@192.168.1.101:5432/sample'
  3. engine = sqlalchemy.create_engine(url, echo=True)






使用するドライバーは使えるものを自動的に探してくれるようです。


url = 'postgresql://pgadmin:password@192.168.1.101:5432/sample'



このように、ドライバーの具体名を指定しなくても接続出来ました。





Declare a Mapping



テーブルとオブジェクトのマッピングを定義していきます。

id,name,kanaという3つのフィールドを持つ「students」テーブルを定義してみました。


Base.metadata.create_all(engine)



で、定義されたオブジェクトにマッチするテーブルが
データベースに作成されます。


  1. import sqlalchemy
  2. import sqlalchemy.ext.declarative
  3. Base = sqlalchemy.ext.declarative.declarative_base()
  4. class Student(Base):
  5.     __tablename__ = 'students'
  6.     id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
  7.     name = sqlalchemy.Column(sqlalchemy.String)
  8.     kana = sqlalchemy.Column(sqlalchemy.String)
  9. url = 'postgresql://pgadmin:password@192.168.1.101:5432/sample'
  10. engine = sqlalchemy.create_engine(url, echo=True)
  11. # スキーマ作成
  12. Base.metadata.create_all(engine)





プログラムを実行してみると、sampleデータベースに
「students」「students_id_seq」の2つのテーブルが作成されました。


Schema |     Name     | Type | Owner
--------+-----------------+----------+---------
public | students        | table    | pgadmin
public | students_id_seq | sequence | pgadmin



※シーケンスが作成されたのはPostgreSQLだからだと思います。
MySQLだと作成されないのかと。


作成されたstudentsテーブルの内容は以下のとおり。


Column |     Type        |                     Modifiers                    
--------+-------------------+-------------------------------------------------------
id     | integer         | not null default nextval('students_id_seq'::regclass)
name | character varying |
kana | character varying |
Indexes:
    "students_pkey" PRIMARY KEY, btree (id)









サイズの指定



一旦studentsテーブルをドロップ。
プログラムを一部変更し、Stringにサイズを指定してみます。


  1. import sqlalchemy
  2. import sqlalchemy.ext.declarative
  3. Base = sqlalchemy.ext.declarative.declarative_base()
  4. class Student(Base):
  5.     __tablename__ = 'students'
  6.     id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
  7.     name = sqlalchemy.Column(sqlalchemy.String(20))
  8.     kana = sqlalchemy.Column(sqlalchemy.String(40))
  9. url = 'postgresql://pgadmin:password@192.168.1.101:5432/sample'
  10. engine = sqlalchemy.create_engine(url, echo=True)
  11. # スキーマ作成
  12. Base.metadata.create_all(engine)





指定通りのサイズでテーブルが作成されました。


Column |         Type         |                     Modifiers                    
--------+-----------------------+-------------------------------------------------------
id     | integer             | not null default nextval('students_id_seq'::regclass)
name | character varying(20) |
kana | character varying(40) |
Indexes:
    "students_pkey" PRIMARY KEY, btree (id)









Create an Instance of the Mapped Class



マッピングの定義を行ったStudentクラスにデータを設定してみます。


  1. import sqlalchemy
  2. import sqlalchemy.ext.declarative
  3. Base = sqlalchemy.ext.declarative.declarative_base()
  4. class Student(Base):
  5.     __tablename__ = 'students'
  6.     id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
  7.     name = sqlalchemy.Column(sqlalchemy.String(20))
  8.     kana = sqlalchemy.Column(sqlalchemy.String(40))
  9. url = 'postgresql://pgadmin:password@192.168.1.101:5432/sample'
  10. engine = sqlalchemy.create_engine(url, echo=True)
  11. student = Student(name='西住 みほ', kana='ニシズミ ミホ')
  12. print(student.name)
  13. print(student.kana)
  14. print(student.id)




実行すると、name、kanaには指定した値が、idにはNoneが設定されている状態になります。
このオブジェクトを経由して、データベースにデータを登録することになります。


$ python sample.py
西住 みほ
ニシズミ ミホ
None







Creating a Session



テーブルのマッピングと、実際にマッピングしたオブジェクトに値を設定してみました。
このオブジェクトをデータベースに登録するには「Session」が必要になります。

sqlalchemy.ormのimportを追加。
sessionmakerでSessionを作成します。


  1. import sqlalchemy
  2. import sqlalchemy.orm
  3. import sqlalchemy.ext.declarative
  4. Base = sqlalchemy.ext.declarative.declarative_base()
  5. class Student(Base):
  6.     __tablename__ = 'students'
  7.     id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
  8.     name = sqlalchemy.Column(sqlalchemy.String(20))
  9.     kana = sqlalchemy.Column(sqlalchemy.String(40))
  10. url = 'postgresql://pgadmin:password@192.168.1.101:5432/sample'
  11. engine = sqlalchemy.create_engine(url, echo=True)
  12. # セッションを作成
  13. Session = sqlalchemy.orm.sessionmaker(bind=engine)
  14. session = Session()
  15. student = Student(name='西住 みほ', kana='ニシズミ ミホ')








Adding New Objects



セッションにデータを追加します。
合わせて、追加したデータを検索してみます。


  1. import sqlalchemy
  2. import sqlalchemy.orm
  3. import sqlalchemy.ext.declarative
  4. Base = sqlalchemy.ext.declarative.declarative_base()
  5. class Student(Base):
  6.     __tablename__ = 'students'
  7.     id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
  8.     name = sqlalchemy.Column(sqlalchemy.String(20))
  9.     kana = sqlalchemy.Column(sqlalchemy.String(40))
  10. url = 'postgresql://pgadmin:password@192.168.1.101:5432/sample'
  11. engine = sqlalchemy.create_engine(url, echo=True)
  12. # セッションを作成
  13. Session = sqlalchemy.orm.sessionmaker(bind=engine)
  14. session = Session()
  15. # 登録したいオブジェクトを定義
  16. student = Student(name='西住 みほ', kana='ニシズミ ミホ')
  17. # セッションに追加
  18. session.add(student)
  19. # 追加したデータを検索
  20. found_student = session.query(Student).filter_by(name='西住 みほ').first()
  21. print(found_student.name)
  22. print(found_student.kana)
  23. print(found_student.id)





実行してみると、自分で指定した名前の他に、idも値が設定されています。


西住 みほ
ニシズミ ミホ
1




もう一度実行すると、idのカウントが増えていきます。


西住 みほ
ニシズミ ミホ
2




しかし、データベースのレコードは0件数のまま。
明示的なコミットが必要です。






セッションにはadd_allで複数のデータを登録可能です。

session.dirtyで変更前のデータ。
session.newで変更後のデータが取得出来ました。


  1. import sqlalchemy
  2. import sqlalchemy.orm
  3. import sqlalchemy.ext.declarative
  4. Base = sqlalchemy.ext.declarative.declarative_base()
  5. class Student(Base):
  6.     __tablename__ = 'students'
  7.     id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
  8.     name = sqlalchemy.Column(sqlalchemy.String(20))
  9.     kana = sqlalchemy.Column(sqlalchemy.String(40))
  10.     
  11.     # デバッグ用
  12.     def __repr__(self):
  13.     return '<name=%s, kana=%s>' % (self.name, self.kana)
  14. url = 'postgresql://pgadmin:password@192.168.1.101:5432/sample'
  15. engine = sqlalchemy.create_engine(url, echo=True)
  16. # セッションを作成
  17. Session = sqlalchemy.orm.sessionmaker(bind=engine)
  18. session = Session()
  19. # 登録したいオブジェクトを定義
  20. student = Student(name='西住 みほ', kana='ニシズミ ミホ')
  21. # セッションに追加
  22. session.add(student)
  23. # 複数データを一括登録
  24. session.add_all([
  25.     Student(name='武部 沙織', kana='タケベ サオリ'),
  26.     Student(name='五十鈴 華', kana='イスズ ハナ'),
  27.     Student(name='秋山 優花里', kana='アキヤマ ユカリ'),
  28.     Student(name='冷泉 麻子', kana='レイゼイ マコ'),
  29.     ])
  30. print('session.dirty')
  31. print(session.dirty)
  32. print('session.new')
  33. print(session.new)
  34. # データを確定
  35. session.commit()




 
session.commit()を実行することで、データ登録を確定します。

登録後、studentsテーブルを検索してみるとちゃんと登録されてました。



sample=# select * from students;
id |        name        |         kana        
----+--------------------+--------------------------
18 | 西住 みほ    | ニシズミ ミホ
19 | 武部 沙織    | タケベ サオリ
20 | 五十鈴 華    | イスズ ハナ
21 | 秋山 優花里 | アキヤマ ユカリ
22 | 冷泉 麻子    | レイゼイ マコ
(5 rows)


関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2014/03/27(木) 22:04:13|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<SQLAlchemyの使い方2 データの更新と検索、ロールバック | ホーム | Python SQLAlchemyの接続文字列一覧>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1373-c78e4419
この記事にトラックバックする(FC2ブログユーザー)