sqlalchemy文档资料翻译(二)

来源:互联网 发布:火影忍者佐助的刀淘宝 编辑:程序博客网 时间:2024/05/22 06:21

[程序]sqlalchemy文档资料翻译(二) -- 对象关系教程

英文原文链接地址

本教程我们主要讨论用于通过数据库表示存取Python对象的基础SQLAlchemy对象关系映射脚本。本教程中采用doctest格式,及每个 >>> 行表示通过python命令行输入的内容,而接下来的文字内容则表示期望获得的返回值。

  • 版本检查

比较快捷的检查当前SQLAlchemy是否为最新版本的方式如下:

>>> import sqlalchemy

>>> sqlalchemy.__version__

0.6.0

  • 连接数据库

本教程中我们将仅使用SQLite内存数据库。连接数据库我们采用create_engine()方法:

>>> from sqlalchemy import create_engine

>>> engine = create_engine("sqlite:///:memory:", echo = True)

echo标识用于设置通过python标准日志模块完成的SQLAlchemy日志系统。当开启日志功能,我们就可以看到所有的SQL生成代码。如果你已经熟悉了该教程并希望少一些输出信息,那么可以将其设置为False。本教程会将生成的SQL代码标识在代码中。

  • 定义和创建数据表

接下来我们将告知SQLAlchemy我们需要创建的表。我们会从一个单一的表users开始,该表用于记录使用我们系统的用户信息(假设我们的系统是一个web应用)。我们约定我们的数据表集中在MetaData对象中,通过Table对象来创建,方式和SQL语言的CREATE TABLE类似:

>>> from sqlalchemy importTable,Column, Integer,String,MetaData, ForeignKey
>>> metadata = MetaData()
>>> users_table = Table('users',metadata,
...     Column('id',Integer,primary_key=True),
...     Column('name',String),
...     Column('fullname',String),
...     Column('password',String)
... )

Database Meta Data 涉及到如何定义Table 对象的所有内容,以及如何从一个已知的数据库中获取相关数据表定义(被誉为自省)。

接下来,我们就可以通过调用 create_all() 命令发出来自元数据的CREATE TABLE 命令并将其传递给指向我们数据库的 engine 实例。该方法在调用的时候会先检查已经存在的表结构,因此重复多次的调用该方法是安全的。

>>> metadata.create_all(engine)

SQL代码:
PRAGMA table_info("users")
()
CREATE TABLE users (
    id INTEGER NOT NULL,
    name VARCHAR,
    fullname VARCHAR,
    password VARCHAR,
    PRIMARY KEY (id))
()
COMMIT

注意:
熟悉 CREATE TABLE命令的用户可能会注意到此处的 VARCHAR 并没有指定长度,在 SQLite 和 Postgresql中,这是一种合法的数据类型,但是在其他数据库中,这是不允许的。因此如果是在其他数据中运行本示例,你还需要为String 类型指定长度:
... Column('name', String(50))
String 的长度以及其他可控精度的字段名如:Integer,Numeric等等,在 SQLAlchemy 中仅在创建表的时候使用。
另外,对于 Firebird 和 Oracle 等需要通过序列化方式来创建新主键标识符的数据库,SQLAlchemy 并不会自动为其生成。对于这样的情况,你必须指定Sequence 生成:
>>> from sqlalchemy import Sequence
... Column('id', Integer,Sequence('user_id_seq'),primary_key = True)
一个完整的 Table 实例如下:
>>> users_table = Table('users',metadata,
... Column('id', Integer,Sequence('user_id_seq'),primary_key = True),
... Column('name', String(50)),
... Column('fullname', String(50)),
... Column('password', String(12)))

  • 定义一个需要映射的 Python 类

Table 对象负责定义和数据库相关的信息,但其并不负责我们程序使用的对象的定义及操作,SQLAlchemy将这视为另一件事。为了对应我们的 users 表,我们先要创建一个基础的 User 类。这仅仅需要从 python 的基础类中继承:

>>> class User(object):...     def __init__(self, name, fullname, password):...         self.name = name...         self.fullname = fullname...         self.password = password......     def __repr__(self):...        return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)

为了方便类中拥有 __init__() 和 __repr__() 函数。这些函数当然也是可选的,也可以是其他形式的。SQLAlchemy 并不会直接调用__init__() 函数。

  • 设置映射

当拥有了 users_table 和 User 类后,我们现在需要将其映射到一起。SQLAlchemy ORM 包隆重登场。我们将使用mapper 方法来创建users_table 和 User之间的映射:

>>> from sqlalchemy.orm import mapper>>> mapper(User, users_table) <Mapper at 0x...; User>

mapper() 方法将会创建一个新的 Mapper 对象,该对象会和我们的类关联。现在我们来创建并检查一个 User 对象:

>>> ed_user = User('ed','Ed Jones','edspassword')
>>> ed_user.name
'ed'
>>> ed_user.password
'edspassword'
>>> str(ed_user.id)
'None'

__init__() 方法中并未指定的属性 id 也会存在,因为 users_table 对象中拥有 id 列。默认情况下,mapper 会为Table 中的所有出现的列创建类属性。这些类属性以python描述的形式存在,并为映射类定义相关的仪器。这些仪器的功能相当丰富,包括跟踪变化以及必要时自动从数据库读取新数据的能力。由于我们还没有通知 SQLAlchemy 去将EdJones 这条记录持久化到数据库中,因此他的 id 仍然是 None 。当我们在稍后持久化本对象后,该属性将会自动被一个新生成的值刷新。

  • 在 Declaratively 中一次性完成创建 Table, Class 和 Mapper

我们之前介绍的配置方法包含 Table,用户定义的类,以及调用映射 mapper()。这演示了经典的 SQLAlchemy 用法,该用法以最大的灵活性为重。但是大部分的应用不需要这个级别的灵活性,此时 SQLAlchemy 提供了一种叫做declarative 的替代的快速配置方案。对于大部分的应用程序来说,这样的配置方式已经足够了。我们之前介绍的例子用该方法描述如下:

>>> from sqlalchemy.ext.declarative import declarative_base>>> Base = declarative_base()>>> class User(Base):...     __tablename__ = 'users'......     id = Column(Integer, primary_key=True)...     name = Column(String)...     fullname = Column(String)...     password = Column(String)......     def __init__(self, name, fullname, password):...         self.name = name...         self.fullname = fullname...         self.password = password......     def __repr__(self):...        return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)

如上所述,declarative_base() 函数负责定义一个名为 Base 的新类,该类是我们使用的所有拥有 ORM 功能的类的基类。注意此处我们在定义 Column 对象时并没有指定 "name" 字段,因为该字段可以从给定的属性名推断得出。

在 User 中通过 declarative_base() 创建的底层 Table 对象可以通过__table__属性访问:

>>> users_table = User.__table__

其中 MetaData 对象也是可以访问的:

>>> metadata = Base.metadata

关于 declarative 的详细文档可以在 API Reference 关于 declarative 的章节中找到。

如今 SQLAlchemy 通过第三方库 Elixir 提供另一种 declarative 方法。这是一种拥有更强功能的配置构架产品,他包含很多更高级的内置映射配置。和 declarative 一样,一旦定义了类及映射, ORM 用法和经典的 SQLAlchemy 配置一致。

<未完…待续>

0 0
原创粉丝点击