Psycopg - PostgreSQL database adapter for Python
基本模块用法
Psycopg 的基本用法共同于所有遵循 DB API 2.0 协议实现的数据库适配器
Passing parameters to SQL queries
对于我来说这是最重要的一部分内容
Psycopg 根据 Python 变量的类型将变量转换为 SQL 值。Python 类型确定了用于将对象转换为与 Postgresql 相匹配的字符串的函数。大部分标准 Python 类型已经适配了正确的 SQL 表达。
传递参数给 SQL 语句发生在如 cursor.execute() 这样的函数中,其通过在 SQL 语句中使用 %s 占位符并在函数的第二个参数中传递值序列。
命名参数也是支持的,在查询中使用 %(name)s 占位符并在映射中指定值。使用命名参数允许以任意的次序指定值,也允许同一值在查询的几个位置重复。
命名参数其名中不能包含 %, (, ) 三字符。
在使用参数的查询中,为了使用 % 字面量,可以使用 %% 串。
Transactions control 事务控制
Psycopg 中事务由 connection 类控制。缺省情况下,当首次将一个命令发送到数据库时,一个新的事务被创建。其后的命令将在同一个事务环境中执行 - 不仅是第一个 cursor 发出的命令,而且是由同一个连接创建的所有 cursor 都如此。可能任一命令失败,事务即中断,后续命令停止运行,直到 rollback() 方法被调用。
connection 负责了结其事务,通过调用 commit() 或 rollback() 方法。变更即刻持久化于库中。关闭连接使用 closer() 方法或删除连接对象,(使用 del 或 使其 fall out of scope )将导致隐式 rollback 。
connection 可被设置为 autocommit 模式:这样所有执行的命令将立即确认,不能回滚。有几个命令,如 CREATE DATABASE, VACUUM 等需要运行在事务之外。为了能够从 Psycopg 运行这些命令,connection 必须在 autocommit 态。可以使用 autocommit 属性。
告诫:缺省情况下,即使一个简单的 SELECT 也会启动一个事务。在长时间运行的程序中,如果没有进一步的动作,会话将被保持,即“在连接中发呆”,因为几个原因这种状态是不受待见的(会话保持锁,表爆炸)。对于长期存在的脚本,请确保尽快终止事务或使用自动提交连接。
还有几个事务属性能够设置会话范围。详见 set_seesion()
SQL string composition
模块包含着以一种安全便捷的方式动态生成 SQL 的对象和方法。SQL 标识符,如:表名,字段名 不能像查询参数那样传递给 execute() 方法。SQL 查询应在参数合并之前构成。
class psycopg2.sql.Composable(wrapped)
可被用于组成 SQL 字符串的对象的抽象基类。
Composable 对象可被直接传入 execute(), executemany(), copy_expert() ,占用查询串的位置。
Composable 对象可以使用操作符 + 连接:结果为包含连接对象的 Composed 实例。Composable 对象也支持操作符 * : 结果为包含重复请求次数左参的 Composed 实例。
```
query = sql.SQL("select {0} from {1}").format(
sql.SQL(', ').join([sql.Identifier('foo'), sql.Identifier('bar']),
sql.Identifier('table'))
# select "foo", "bar" from "table"
```
class psycopg2.sql.SQL(string)
Composable 表示一段 SQL 语句。
SQL 暴露了 join() 与 format() 方法帮助合并查询的变量部分,创建模板。
参数 string 不接受任何形式的逃逸,所以 SQL 不适合表示变量、标识符或值:应该仅被用于传递常量字符串表示模板或 SQL 语句段,使用其它对象如 Identifier 或 Literal 表示变量部分。
class psycopg2.sql.Placeholder(name=None)
将一个 Composable 对象表示为查询参数占位符。
如果指定 name 则生成命名占位符,否则生成位置占位符。
对象用于生成带有数个参数变量的 SQL 查询。
例子:
names = ['foo', 'bar', 'baz']
q1 = sql.SQL("insert into table ( {} ) values ({}) ")
.format(
sql.SQL('.').join( map( sql.Identifier, names ) ),
sql.SQL('.').join( sql.Placeholder() * len( names ) )
)
# insert into table ("foo", "bar", "baz") values (%s, %s, %s)
q2 = sql.SQL("insert into table ( {} ) values ({}) ")
.format(
sql.SQL('.').join( map( sql.Identifier, names ) ),
sql.SQL('.').join( map( sql.Placeholder, names ) )
)
# insert into table ("foo", "bar", "baz") values (%(foo)s, %(bar)s, %(baz)s)
name
The name of the Placeholder.