[Pylons] SQLAlchemy起步 - II. MetaData和Types
Posted on 2009-01-26 22:14 laogao 閱讀(2471) 評(píng)論(0) 編輯 收藏 所屬分類: On Python在sqlalchemy.schema和sqlalchemy.types這兩個(gè)module中,包含了定義數(shù)據(jù)庫(kù)schema所需要的所有類,如Table、Column、String、Text、Date、Time、Boolean等。還是來(lái)看一個(gè)例子:
?1?from?sqlalchemy.engine?import?create_engine
?2?from?sqlalchemy.schema?import?MetaData,?Table,?Column,?ForeignKey,?Sequence
?3?from?sqlalchemy.types?import?*
?4?
?5?engine?=?create_engine('postgres://test:test@localhost/test',?echo=True)
?6?
?7?metadata?=?MetaData()
?8?metadata.bind?=?engine
?9?
10?book_table?=?Table('book',?metadata,
11?????Column('id',?Integer,?Sequence('seq_pk'),?primary_key=True),
12?????Column('title',?Unicode(255),?nullable=False),
13?)
14?
15?author_table?=?Table('author',?metadata,
16?????Column('id',?Integer,?Sequence('seq_pk'),?primary_key=True),
17?????Column('name',?Unicode(255),?nullable=False),
18?)
19?
20?bookauthor_table?=?Table('bookauthor',?metadata,
21??? Column('book_id',?Integer,?ForeignKey('book.id'),?nullable=False),
22??? Column('author_id',?Integer,?ForeignKey('author.id'),?nullable=False),
23)
24
25metadata.create_all(checkfirst=True)
?2?from?sqlalchemy.schema?import?MetaData,?Table,?Column,?ForeignKey,?Sequence
?3?from?sqlalchemy.types?import?*
?4?
?5?engine?=?create_engine('postgres://test:test@localhost/test',?echo=True)
?6?
?7?metadata?=?MetaData()
?8?metadata.bind?=?engine
?9?
10?book_table?=?Table('book',?metadata,
11?????Column('id',?Integer,?Sequence('seq_pk'),?primary_key=True),
12?????Column('title',?Unicode(255),?nullable=False),
13?)
14?
15?author_table?=?Table('author',?metadata,
16?????Column('id',?Integer,?Sequence('seq_pk'),?primary_key=True),
17?????Column('name',?Unicode(255),?nullable=False),
18?)
19?
20?bookauthor_table?=?Table('bookauthor',?metadata,
21??? Column('book_id',?Integer,?ForeignKey('book.id'),?nullable=False),
22??? Column('author_id',?Integer,?ForeignKey('author.id'),?nullable=False),
23)
24
25metadata.create_all(checkfirst=True)
首先我們還是create_engine,然后新建一個(gè)MetaData對(duì)象,把engine綁上去,接下來(lái),開(kāi)始在metadata中定義表結(jié)構(gòu)(metadata由Table構(gòu)造函數(shù)傳入),我們這里定義了3張表,分別是book、author和bookauthor關(guān)系表(“多對(duì)多”),其中新建一個(gè)Sequence對(duì)象,專門(mén)處理主鍵生成。最后我們通過(guò)執(zhí)行metadata.create_all()創(chuàng)建數(shù)據(jù)庫(kù)表,參數(shù)checkfirst=True表示如果數(shù)據(jù)庫(kù)相關(guān)對(duì)象已經(jīng)存在,則不重復(fù)執(zhí)行創(chuàng)建。
對(duì)于已經(jīng)存在于數(shù)據(jù)庫(kù)中的表,我們可以通過(guò)傳入autoload=True參數(shù)到Table構(gòu)造函數(shù)的方式來(lái)加載現(xiàn)有的表結(jié)構(gòu)到metadata中,而不必挨個(gè)兒再寫(xiě)一遍Column清單。
看到這兒,你也許覺(jué)得挺麻煩,不是么?Django和RoR都是可以直接定義數(shù)據(jù)model類,順帶就把schema也定義了,而不是像這樣單獨(dú)去寫(xiě)表結(jié)構(gòu)的schema,顯得很"底層"。確實(shí),這樣用SQLAlchemy并不是最優(yōu)化的,SQLAlchemy本身并不會(huì)自動(dòng)的幫你做很多事,但它基礎(chǔ)打得很牢。如果你感興趣,也可以先去看一下SQLAlchemy的擴(kuò)展模塊Elixir,通過(guò)Elixir,你可以像Ruby on Rails那樣定義出實(shí)體和關(guān)系("Active Record")。
在稍后的第4部分中,我們會(huì)去了解如何以聲明方式來(lái)更緊湊的定義我們的model/schema(0.5新特性)。鑒于筆者傾向于更強(qiáng)的控制力,所以在這個(gè)系列中就不去介紹SQLAlchemy的其他擴(kuò)展模塊了,如Elixir、SQLSoup等,大家可以根據(jù)需要去找下官方文檔。