SQLBuilder¶
SQLBuilder 中的多个变量包含在 from sqlobject import *
中——有关更多信息,请参阅 相关的 SQLObject 文档。其功能还可以通过 SQLObject 类的特殊 q
属性获得。
SQLExpression¶
SQLExpression 巧妙地覆盖了运算符,使 Python 表达式构建 SQL 表达式——只要你从一个知道如何伪造它的魔术对象开始。
使用 SQLObject,你可以通过访问表类的 q
属性来获取一个魔术对象——这会给你一个表示该字段的对象。所有这些可能更容易在示例中理解
>>> from sqlobject.sqlbuilder import *
>>> person = table.person
# person is now equivalent to the Person.q object from the SQLObject
# documentation
>>> person
person
>>> person.first_name
person.first_name
>>> person.first_name == 'John'
person.first_name = 'John'
>>> name = 'John'
>>> person.first_name != name
person.first_name != 'John'
>>> AND(person.first_name == 'John', person.last_name == 'Doe')
(person.first_name = 'John' AND person.last_name = 'Doe')
大多数运算符都能正常工作:<、>、<=、>=、!=、==、+、-、/、*、**、%。但是,and
、or
和 not
不起作用。你可以改用 &、| 和 ~——但请注意,这些与乘法具有相同的优先级。所以
# This isn't what you want:
>> person.first_name == 'John' & person.last_name == 'Doe'
(person.first_name = ('John' AND person.last_name)) = 'Doe')
# This is:
>> (person.first_name == 'John') & (person.last_name == 'Doe')
((person.first_name = 'John') AND (person.last_name == 'Doe'))
SQLBuilder 还包含函数 AND
、OR
和 NOT
,它们也能工作——我发现这些更容易使用。 AND
和 OR
可以接受任意数量的参数。
你还可以对 SQL 表达式使用 .startswith()
和 .endswith()
——这些将转换为适当的 LIKE
语句,并且所有 %
引用都已为你处理,因此你可以忽略该实现细节。还有一个 LIKE
函数,你可以传递你的字符串,其中 %
表示通配符,与往常一样。
如果你想访问 SQL 函数,请使用 func
变量,如下所示
>> person.created < func.NOW()
要传递常量,请使用 const
变量,它实际上是 func 的别名。
SQL 语句¶
SQLBuilder 实现执行 SQL 语句的对象。SQLObject 在其更高级别的 API 中在内部使用它们,但用户可以使用此中级 API 来执行高级别 API 不支持的 SQL 查询。要使用这些对象,首先构建一个语句对象实例,然后要求连接将该实例转换为 SQL 查询,最后要求连接执行查询并返回结果。例如,对于Select
类
>>> from sqlobject.sqlbuilder import *
>> select = Select(['name', 'AVG(salary)'], staticTables=['employees'],
>> groupBy='name') # create an instance
>> query = connection.sqlrepr(select) # Convert to SQL string:
>> # SELECT name, AVG(salary) FROM employees GROUP BY name
>> rows = connection.queryAll(query) # Execute the query
>> # and get back the results as a list of rows
>> # where every row is a sequence of length 2 (name and average salary)
Select¶
用于构建SELECT
查询的类。接受多个参数,除了items 之外的所有参数都是可选的。使用connection.queryAll(query)
执行查询,并将结果作为行列表返回。
- items:
- 字符串、SQLExpression 或字符串或 SQLExpression 的序列,表示列列表。如果有 q 值 SQLExpression,
Select
会派生 SELECT 查询的表列表。 - where:
- 字符串或 SQLExpression,表示
WHERE
子句。 - groupBy:
- 字符串或 SQLExpression,表示
GROUP BY
子句。 - having:
- 字符串或 SQLExpression,表示
GROUP BY
子句的HAVING
部分。 - orderBy:
- 字符串或 SQLExpression,表示
ORDER BY
子句。 - join:
- JOIN(
LEFT JOIN
等)的(列表)。 - distinct:
- 布尔标志,用于启用
DISTINCT
查询。 - start、end
- 整数。计算
OFFSET
和LIMIT
的方法。 - limit:
- 整数。limit(如果传递)将覆盖end。
- reversed:
- 布尔标志,用于按相反方向执行
ORDER BY
。 - forUpdate:
- 布尔标志,用于启用
SELECT FOR UPDATE
查询。 - staticTables:
- 命名
FROM
表的字符串或 SQLExpression 的序列。如果items 是 Select 无法从中派生表列表的字符串列表,则必须使用此参数。
Insert¶
一个用于构建 INSERT
查询的类。接受多个参数。使用 connection.query(query)
执行查询。
- table:
- 一个字符串,用于指定要
INSERT
的表。必需。 - valueList:
一个 (key, value) 序列或 {key: value} 字典的列表;键是列名。必须传递 valueList 或 values,但不能同时传递。示例
>> insert = Insert('person', valueList=[('name', 'Test'), ('age', 42)]) # or >> insert = Insert('person', valueList=[{'name': 'Test'}, {'age': 42}]) >> query = connection.sqlrepr(insert) # Both generate the same query: # INSERT INTO person (name, age) VALUES ('Test', 42) >> connection.query(query)
- values:
一个字典 {key: value};键是列名。必须传递 valueList 或 values,但不能同时传递。示例
>> insert = Insert('person', values={'name': 'Test', 'age': 42}) >> query = connection.sqlrepr(insert) # The query is the same # INSERT INTO person (name, age) VALUES ('Test', 42) >> connection.query(query)
该类的实例工作速度快,因此适合于批量插入。如果需要使用运行大量 INSERT
查询的 SQLObject 来填充数据库,则此类是最佳选择。
Update¶
一个用于构建 UPDATE
查询的类。接受多个参数。使用 connection.query(query)
执行查询。
- table:
- 一个字符串,用于指定要
UPDATE
的表。必需。 - values:
- 一个字典 {key: value};键是列名。必需。
- where:
- 一个可选的字符串或 SQLExpression,表示
WHERE
子句。
示例
>> update = Update('person',
>> values={'name': 'Test', 'age': 42}, where='id=1')
>> query = connection.sqlrepr(update)
# UPDATE person SET name='Test', age=42 WHERE id=1
>> connection.query(query)
Delete¶
一个用于构建 DELETE FROM
查询的类。接受多个参数。使用 connection.query(query)
执行查询。
- table:
- 一个字符串,用于指定要
UPDATE
的表。必需。 - where:
- 一个可选的字符串或 SQLExpression,表示
WHERE
子句。必需。如果您需要删除所有行,请传递where=None
;这是一项安全措施。
示例
>> update = Delete('person', where='id=1')
>> query = connection.sqlrepr(update)
# DELETE FROM person WHERE id=1
>> connection.query(query)
Union¶
一个用于构建 UNION
查询的类。接受多个参数 - Select
查询。使用 connection.queryAll(query)
执行查询并获取结果。
示例
>> select1 = Select(['min', func.MIN(const.salary)], staticTables=['employees'])
>> select2 = Select(['max', func.MAX(const.salary)], staticTables=['employees'])
>> union = Union(select1, select2)
>> query = connection.sqlrepr(union)
# SELECT 'min', MIN(salary) FROM employees
# UNION
# SELECT 'max', MAX(salary) FROM employees
>> rows = connection.queryAll(query)
嵌套 SQL 语句(子查询)¶
有一些特殊运算符接收 SQL 语句作为参数。这些运算符是 IN
、NOTIN
、EXISTS
、NOTEXISTS
、SOME
、ANY
和 ALL
。考虑以下示例:您希望使用 deleteMany 从表中删除记录。但是,执行此操作的条件取决于另一个表。
您会希望以下内容有效
>> PersonWorkplace.deleteMany(where=
((PersonWorkplace.q.WorkplaceID==Workplace.q.id) &
(Workplace.q.id==SOME_ID)))
但这不起作用!但是,您无法在 deleteMany 调用中执行联接。要解决此问题,请使用 IN
>> PersonWorkplace.deleteMany(where=
IN(PersonWorkplace.q.WorkplaceID,
Select(Workplace.q.id, Workplace.q.id==SOME_ID)))