Read Sean

Read me, read Sean.
posts - 508, comments - 655, trackbacks - 9, articles - 4

[Pylons] SQLAlchemy起步 - II. MetaData和Types

Posted on 2009-01-26 22:14 laogao 阅读(2433) 评论(0)  编辑  收藏 所属分类: On Python

在sqlalchemy.schema和sqlalchemy.types这两个module中,包含了定义数据库schema所需要的所有类,如Table、Column、String、Text、Date、Time、Boolean等。还是来看一个例子:

 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)

首先我们还是create_engine,然后新建一个MetaData对象,把engine绑上去,接下来,开始在metadata中定义表结构(metadata由Table构造函数传入),我们这里定义了3张表,分别是book、author和bookauthor关系表(“多对多”),其中新建一个Sequence对象,专门处理主键生成。最后我们通过执行metadata.create_all()创建数据库表,参数checkfirst=True表示如果数据库相关对象已经存在,则不重复执行创建。

对于已经存在于数据库中的表,我们可以通过传入autoload=True参数到Table构造函数的方式来加载现有的表结构到metadata中,而不必挨个儿再写一遍Column清单。

看到这儿,你也许觉得挺麻烦,不是么?Django和RoR都是可以直接定义数据model类,顺带就把schema也定义了,而不是像这样单独去写表结构的schema,显得很"底层"。确实,这样用SQLAlchemy并不是最优化的,SQLAlchemy本身并不会自动的帮你做很多事,但它基础打得很牢。如果你感兴趣,也可以先去看一下SQLAlchemy的扩展模块Elixir,通过Elixir,你可以像Ruby on Rails那样定义出实体和关系("Active Record")。

在稍后的第4部分中,我们会去了解如何以声明方式来更紧凑的定义我们的model/schema(0.5新特性)。鉴于笔者倾向于更强的控制力,所以在这个系列中就不去介绍SQLAlchemy的其他扩展模块了,如Elixir、SQLSoup等,大家可以根据需要去找下官方文档。


只有注册用户登录后才能发表评论。


网站导航: