Web2py - 数据库抽象层

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

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

DAL 的一些重要功能是 −

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

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

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

DAL 入门

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

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

以下步骤用于实现 DAL −

步骤 1 - DAL 构造函数

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

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

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

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

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

SQLite 有两个缺点。

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

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

步骤 2 - 表构造函数

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

例如 −

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

上面的方法也用在Table构造函数中。 表构造函数的语法是相同的。 第一个参数是表名称,后面是字段列表。 字段构造函数采用以下参数 −

Sr.No 参数和用法
1

字段名称

表中字段的名称。

2

字段类型

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

3

Length

定义最大长度。

4

default = None

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

5

update = None

这与默认值相同,但该值仅在更新时使用,而不在插入时使用。

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

它有助于获取选择的 SQL 语句。 例如,考虑一个名为"person"的表,我们需要找到名为"ABC"的人员列表。

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

SQL 语句输出 −

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

_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 需要自行处理分页。