系统说明书 文章模板

-- Jerry Marx [2004-09-17 01:52:14]

The twisted.enterprise.row module is a method of interfacing simple python objects with rows in relational database tables. It has two components: the RowObject class which developers sub-class for each relational table that their code interacts with, and the Reflector which is responsible for updates, inserts, queries and deletes against the database.

twisted.enterprise.row模块是简单Python对象和关系数据库数据表中的行之间交互的一种方法.它有两个组件:RowObject类,开发人员通过可以子类化这个类来和关系数据库的表交互;Reflector类,它的职责是更新,插入,查询和删除数据库中的数据.

The row module is intended for applications such as on-line games, and websites that require a back-end database interface. It is not a full functioned object-relational mapper for python - it deals best with simple data types structured in ways that can be easily represented in a relational database. It is well suited to building a python interface to an existing relational database, and slightly less suited to added database persistance to an existing python application.

行模式是为例如在线游戏和网站而设计的,这些应用需要一个后台的数据库接口.它并不是一个关系对象函数在Python的完整映射 - 它和关系数据库表现的简单数据类型结构协作的非常好.很适合用来构建一个python接口来和已有的关系数据库交互,而对于为已有的python应用添加数据库实现持久数据稍微有些不适合.

If row does not fit your model, you will be best off using the low-level database API directly, or writing your own object/relational layer on top of it.

如果row不适合你的模型,最好直接使用底层的数据库API,或者在API的基础上包装自己的对象/相关层.

1. 类定义(Class Definitions)

To interface to relational database tables, the developer must create a class derived from the twisted.enterprise.row.RowObject class for each table. These derived classes must define a number of class attributes which contains information about the database table that class corresponds to. The required class attributes are:

为了访问关系数据库表,开发人员必须为每个表创建一个继承自twisted.enterprise.row.RowObject类的子类.这些子类需要定义一些属性来描述对应的表的信息.必须的类属性如下所示:

  • rowColumns - list of the column names and types in the table with the correct case
    • 表中列名和类型的列表(并且有正确的大小写).
  • rowKeyColumns - list of key columns in form: [(columnName, typeName)]
    • 以[(columnName, typeName)]形式纪录的列关键字列表.
  • rowTableName - the name of the database table
    • 数据表名称.

There are also two optional class attributes that can be specified:

还有两个可以指定的可选属性.

  • rowForeignKeys - list of foreign keys to other database tables in the form: [(tableName, [(childColumnName, childColumnType), ...], [(parentColumnName, parentColumnType), ...], containerMethodName, autoLoad]
    • 外部关键字列表,以形式[(tableName, [(childColumnName, childColumnType), ...], [(parentColumnName, parentColumnType), ...], containerMethodName, autoLoad]列出.
  • rowFactoryMethod - a method that creates instances of this class
    • 创建这个类的实例的方法.

For example:

例如:

   1 class RoomRow(row.RowObject):
   2     rowColumns       = [("roomId",  "int"),
   3                         ("town_id", "int"),
   4                         ("name",    "varchar"),
   5                         ("owner",   "varchar"),
   6                         ("posx",    "int"),
   7                         ("posy",    "int"),
   8                         ("width",   "int"),
   9                         ("height",  "int")]
  10     rowKeyColumns    = [("roomId",  "int4")]
  11     rowTableName     = "testrooms"
  12     rowFactoryMethod = [testRoomFactory]

The items in the rowColumns list will become data members of classes of this type when they are created by the Reflector.

rowcolumns的各项会在他们被Reflector创建的时候成为类的数据成员.

2. 初始化(Initialization)

The initialization phase builds the SQL for the database interactions. It uses the system catalogs of the database to do this, but requires some basic information to get started. The class attributes of the classes derived from RowClass are used for this. Those classes are passed to a Reflector when it is created.

初始化阶段构在为和数据库交互的SQL语句.它使用数据库的系统目录,但还是要求一些基本的信息才能开始.继承自RowClass的类的属性就是为了提供这些信息.当Reflector创建的时候这些类被传递给它.

There are currently two available reflectors in Twisted Enterprise, the SQL Reflector for relational databases which uses the python DB API, and the XML Reflector which uses a file system containing XML files. The XML reflector is currently extremely slow.

现在Twisted Enterprise里有两个可用的reflector,为关系数据库服务的SQL Reflector使用了python的DB API,还有一个XML Reflector使用了包含XML文件的文件系统.XML reflector现在非常慢.

An example class list for the RoomRow class we specified above using the SQLReflector:

下面这个例子使用了SQLRelfector:

   1 from twisted.enterprise.sqlreflector import SQLReflector
   2 
   3 dbpool = adbapi.ConnectionPool("pyPgSQL.PgSQL")
   4 reflector = SQLReflector( dbpool, [RoomRow] )

3. 创建一个行对象(Creating Row Objects)

There are two methods of creating RowObjects - loading from the database, and creating a new instance ready to be inserted.

创建RowObject有两个方法 - 从数据库加载,创建一个将要被插入的新的实例.

To load rows from the database and create RowObject instances for each of the rows, use the loadObjectsFrom method of the Reflector. This takes a tableName, an optional user data parameter, and an optional where clause. The where clause may be omitted which will retrieve all the rows from the table. For example:

从数据库加载行并且为每行都创建一个RowObject实例,可以使用Reflector的方法loadObjectFrom.它需要一个tableName,一个可选的用户数据参数,一个可选的where子句.当需要找到表的所有行的时候where子句可以被忽略.例如:

   1 def gotRooms(rooms):
   2     for room in rooms:
   3         print "Got room:", room.id
   4 
   5 d = reflector.loadObjectsFrom("testrooms",
   6                               whereClause=[("id", reflector.EQUAL, 5)])
   7 d.addCallback(gotRooms)

For more advanced RowObject construction, loadObjectsFrom may use a factoryMethod that was specified as a class attribute for the RowClass derived class. This method will be called for each of the rows with the class object, the userData parameter, and a dictionary of data from the database keyed by column name. This factory method should return a fully populated RowObject instance and may be used to do pre-processing, lookups, and data transformations before exposing the data to user code. An example factory method:

   1 def testRoomFactory(roomClass, userData, kw):
   2     newRoom = roomClass(userData)
   3     newRoom.__dict__.update(kw)
   4     return newRoom

The last method of creating a row object is for new instances that do not already exist in the database table. In this case, create a new instance and assign its primary key attributes and all of its member data attributes, then pass it to the insertRow method of the Reflector. For example:

newRoom = RoomRow()

  • newRoom.assignKeyAttr("roomI", 11) newRoom.town_id = 20 newRoom.name = 'newRoom1' newRoom.owner = 'fred' newRoom.posx = 100 newRoom.posy = 100 newRoom.width = 15 newRoom.height = 20 reflector.insertRow(newRoom).addCallback(onInsert)

This will insert a new row into the database table for this new RowObject instance. Note that the assignKeyAttr method must be used to set primary key attributes - regular attribute assignment of a primary key attribute of a rowObject will raise an exception. This prevents the database identity of RowObject from being changed by mistake.

4. 表之前的关系(Relationships Between Tables)

5. 复制行对象(Duplicate Row Objects)

6. 更新行对象(Updating Row Objects)

7. 删除行对象(Deleting Row Objects)