Web2py - 数据库抽象层



数据库抽象层 (DAL) 被认为是 web2py 的主要优势。DAL 为底层的 SQL 语法提供了一个简单的应用程序编程接口 (API)。

在本章中,我们将了解 DAL 的一些非平凡应用,例如构建查询以有效地按标签搜索以及构建分层类别树。

DAL 的一些重要特性包括:

  • web2py 包含一个数据库抽象层 (DAL),这是一个将 Python 对象映射到数据库对象的 API。数据库对象可以是查询、表和记录。

  • DAL 使用指定的数据库后端方言动态生成实时 SQL,因此开发人员不必编写完整的 SQL 查询。

  • 使用 DAL 的主要优点是应用程序可以与不同类型的数据库移植。

DAL 入门

大多数 web2py 应用程序都需要数据库连接。因此,构建数据库模型是应用程序设计的首要步骤。

考虑一个新创建的名为 “helloWorld” 的应用程序。数据库在应用程序的 Models 下实现。所有相应应用程序的模型都包含在一个名为 models/db_custom.py 的文件中。

实现 DAL 使用以下步骤:

步骤 1 - DAL 构造函数

建立数据库连接。这是使用 DAL 对象创建的,也称为 DAL 构造函数。

db = DAL ('sqlite://storage.sqlite')

DAL 的一个显著特点是它允许与同一个数据库或不同的数据库(甚至不同类型的数据库)进行多个连接。可以观察到,此行已存在于 models/db.py 文件中。因此,除非您删除了它或需要连接到不同的数据库,否则您可能不需要它。默认情况下,web2py 连接到存储在 storage.sqlite 文件中的 SQLite 数据库。

此文件位于应用程序的 databases 文件夹中。如果该文件不存在,则在第一次执行应用程序时由 web2py 创建。

SQLite 速度很快,并将所有数据存储在一个文件中。这意味着您的数据可以很容易地从一个应用程序传输到另一个应用程序。事实上,SQLite 数据库由 web2py 与应用程序一起打包。它提供完整的 SQL 支持,包括翻译、联接和聚合。

SQLite 有两个缺点。

  • 一个是它不强制执行列类型,并且除了添加和删除列之外,没有 ALTER TABLE。

  • 另一个缺点是任何需要写入访问权限的事务都会锁定整个数据库。

步骤 2 - 表构造函数

一旦建立了与数据库的连接,我们就可以使用 define_table 方法来定义新表。

例如:

db.define_table('invoice',Field('name'))

上述方法也用于表构造函数中。表构造函数的语法相同。第一个参数是表名,后面跟着一个 Field(s) 列表。字段构造函数采用以下参数:

序号 参数和用法
1

字段名称

表中字段的名称。

2

字段类型

采用任何数据类型的值,例如字符串(默认)、文本、布尔值、整数等等。

3

长度

定义最大长度。

4

default = None

这是插入新记录时的默认值。

5

update = None

这与 default 的作用相同,但该值仅在更新时使用,而不是在插入时使用。

6

Notnull

这指定字段值是否可以为 NULL。

7

readable = True

这指定字段在表单中是否可读。

8

writable = True

这指定字段在表单中是否可写。

9

label = "Field Name"

这是要在表单中为此字段使用的标签。

define_table 方法还采用三个命名参数:

语法

db.define_table('....',migrate=True, fake_migrate=False, format = '%(id)s')
  • migrate = True - 这指示 web2py 在表不存在时创建表,或者在表与模型定义不匹配时更改表。

  • fake_migrate = False - 如果模型与数据库表内容匹配,则设置 fake_migrate = True,这有助于 web2py 重新构建数据。

  • format = '%(id)s' - 这是一个格式字符串,它确定如何表示给定表上的记录。

生成原始 SQL

使用 DAL,我们可以建立到数据库的连接,并使用表构造函数和字段构造函数创建新表及其字段。

有时,需要生成 SQL 语句以符合必要的输出。web2py 包含各种函数,有助于生成原始 SQL,如下所示:

_insert

它有助于获取给定表的插入语句。例如:

print db.person._insert(name ='ABC')

它将检索名为“person”表的插入语句。

SQL 语句输出:

INSERT INTO person(name) VALUES ('ABC');

_count

它有助于获取 SQL 语句,该语句给出记录的数量。例如,考虑一个名为“person”的表,我们需要查找名为“ABC”的人员数量。

print db(db.person.name ==' ABC ')._count()

SQL 语句输出:

SELECT count(*) FROM person WHERE person.name = ' ABC ';

_select

它有助于获取 select SQL 语句。例如,考虑一个名为“person”的表,我们需要查找名为“ABC”的人员列表。

print db(db.person.name == ' ABC ')._select()

SQL 语句输出:

SELECT person.name FROM person WHERE person.name = ' ABC ';

_delete

它有助于获取delete SQL 语句。例如,考虑名为“person”的表,我们需要删除名为“ABC”的语句。

print db(db.person.name == ' ABC ')._delete()

SQL 语句输出:

DELETE FROM person WHERE person.name = ' ABC ';4

_update

它有助于获取更新的 SQL 语句。例如,考虑名为“person”的表,我们需要使用其他值更新列名。

print db(db.person.name == ' ABC ')._update()

SQL 语句输出:

UPDATE person SET WHERE person.name = ’Alex’;

DAL 的问题(陷阱)

SQLite

SQLite 缺乏删除或更改列的支持。从表中删除字段会使其在数据库中保持活动状态,因此 web2py 将不知道所做的任何更改。

在这种情况下,需要设置fake_migrate = True,这将有助于重新定义元数据,以便任何更改(例如更改或删除)都将被 web2py 了解。

SQLite 不支持布尔类型。为此,web2py 在内部将布尔值映射到 1 个字符的字符串,其中 'T' 和 'F' 分别代表trueFalse

MySQL

MySQL 不支持 ALTER TABLE 功能。因此,数据库迁移涉及多个提交。可以通过在定义数据库时设置参数fake_migrate = True 来避免这种情况,这将保留所有元数据。

Oracle

Oracle 不支持记录分页功能。它也不支持 OFFSET 或 limit 关键字。为此,web2py 在 DAL 的复杂三向嵌套选择帮助下实现分页。如果使用了 Oracle 数据库,则 DAL 需要自行处理分页。

广告