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构造函数中也使用了上述方法。表构造函数的语法是相同的。第一个参数是表名称,后面是Field(s)列表。字段构造函数采用以下参数 -

先生编号 参数和用法
1

字段名称

表中的字段名称。

2

字段类型

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

3

长度

定义最大长度。

4

默认=无

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

5

更新=无

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

6

不为空

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

7

可读=真

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

8

可写=真

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

9

标签=“字段名称”

这是表单中该字段使用的标签。

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,如下所示 -

_插入

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

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

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

SQL 语句输出 -

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

_数数

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

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

SQL 语句输出 -

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

_选择

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

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

SQL 语句输出 -

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

_删除

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

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

SQL 语句输出 -

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

_更新

它有助于获取更新的 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不支持记录分页功能。它还缺乏对关键字 OFFSET 或 limit 的支持。为此,web2py 借助 DAL 的复杂三向嵌套选择来实现分页。如果使用了 Oracle 数据库,DAL 需要自行处理分页。