版本:1.1.0b2 |发布日期:2016年7月1日

SQLAlchemy 1.1文档

列插入/更新默认值

SQLAlchemy提供了关于在INSERT和UPDATE语句中发生的列级事件的非常丰富的功能集。选项包括:

  • 在INSERT和UPDATE操作期间用作默认值的标量值
  • 在INSERT和UPDATE操作中执行的Python函数
  • INSERT语句中嵌入的SQL表达式(或者在某些情况下预先执行)
  • 嵌入在UPDATE语句中的SQL表达式
  • 在INSERT期间使用的服务器端默认值
  • 在UPDATE期间使用服务器端触发器的标记

所有插入/更新默认值的一般规则是,只有当特定列的值不作为execute()参数传递时才会生效。否则,使用给定的值。

标量默认值

最简单的默认值是用作列的默认值的标量值:

Table("mytable", meta,
    Column("somecolumn", Integer, default=12)
)

上面,如果没有提供其他值,则在INSERT期间,值“12”将被绑定为列值。

标量值也可能与UPDATE语句相关联,尽管这不是很常见(因为UPDATE语句通常在寻找动态的默认值):

Table("mytable", meta,
    Column("somecolumn", Integer, onupdate=25)
)

Python执行的函数

Column.defaultColumn.onupdate关键字参数也接受Python函数。如果没有提供该列的其他值,则在插入或更新时调用这些函数,并将返回的值用于该列的值。下面说明了一个粗略的“序列”,它将一个递增计数器分配给一个主键列:

# a function which counts upwards
i = 0
def mydefault():
    global i
    i += 1
    return i

t = Table("mytable", meta,
    Column('id', Integer, primary_key=True, default=mydefault),
)

应该注意的是,对于真正的“递增序列”行为,通常应该使用数据库的内置功能,这可能包括序列对象或其他自动增量功能。对于主键列,SQLAlchemy在大多数情况下会自动使用这些功能。有关Column的API文档,包括Column.autoincrement标志,以及本章稍后的Sequence密钥生成技术。

To illustrate onupdate, we assign the Python datetime function now to the Column.onupdate attribute:

import datetime

t = Table("mytable", meta,
    Column('id', Integer, primary_key=True),

    # define 'last_updated' to be populated with datetime.now()
    Column('last_updated', DateTime, onupdate=datetime.datetime.now),
)

When an update statement executes and no value is passed for last_updated, the datetime.datetime.now() Python function is executed and its return value used as the value for last_updated. 请注意,我们现在将now作为函数本身,而不调用它(即没有下面的括号) - SQLAlchemy将在语句执行时执行该函数。

上下文相关的默认函数

Column.defaultColumn.onupdate使用的Python函数也可以使用当前语句的上下文来确定一个值。语句的context是一个内部SQLAlchemy对象,它包含有关正在执行的语句的所有信息,包括其源表达式,与之关联的参数和游标。这种上下文关于默认生成的典型用例是访问在该行上插入或更新的其他值。要访问上下文,请提供一个接受单个context参数的函数:

def mydefault(context):
    return context.current_parameters['counter'] + 12

t = Table('mytable', meta,
    Column('counter', Integer),
    Column('counter_plus_twelve', Integer, default=mydefault, onupdate=mydefault)
)

上面我们举例说明了一个默认函数,它将执行所有的INSERT和UPDATE语句,否则就不会提供counter_plus_twelve的值,并且该值将是执行counter列,加上数字12。

While the context object passed to the default function has many attributes, the current_parameters member is a special member provided only during the execution of a default function for the purposes of deriving defaults from its existing values. 对于执行多组绑定参数的单个语句,将为每个参数集调用用户定义的函数,并且为每个执行提供每个单独的参数集的current_parameters

SQL表达式

“default”和“onupdate”关键字也可以通过SQL表达式,包括select语句或直接函数调用:

t = Table("mytable", meta,
    Column('id', Integer, primary_key=True),

    # define 'create_date' to default to now()
    Column('create_date', DateTime, default=func.now()),

    # define 'key' to pull its default from the 'keyvalues' table
    Column('key', String(20), default=keyvalues.select(keyvalues.c.type='type1', limit=1)),

    # define 'last_modified' to use the current_timestamp SQL function on update
    Column('last_modified', DateTime, onupdate=func.utc_timestamp())
    )

Above, the create_date column will be populated with the result of the now() SQL function (which, depending on backend, compiles into NOW() or CURRENT_TIMESTAMP in most cases) during an INSERT statement, and the key column with the result of a SELECT subquery from another table. 当为此表发出UPDATE语句时,last_modified列将填充UTC_TIMESTAMP()(特定于MySQL的函数)的值。

请注意,当使用func函数时,与使用Python datetime函数不同,我们do调用函数,即括号“()因为在这种情况下,我们想要的是函数的返回值,即将被呈现到INSERT或UPDATE语句中的SQL表达式结构。

上面的SQL函数通常是在执行INSERT或UPDATE语句的情况下“内联”执行的,也就是说,执行一条语句,将给定的表达式或子查询嵌入到语句的VALUES或SET子句中。尽管在某些情况下,函数是事先在自己的SELECT语句中“预执行”的。以下所有情况都是如此:

  • 该列是主键列
  • 数据库方言不支持可用的cursor.lastrowid存取器(或等价物);目前包括PostgreSQL,Oracle和Firebird,以及一些MySQL方言。
  • 方言不支持“RETURNING”子句或类似方法,或者将implicit_returning标志设置为False支持RETURNING的方言目前包括Postgresql,Oracle,Firebird和MS-SQL。
  • 该语句是单个执行,即只提供一组参数,不使用“executemany”行为
  • Insert()Update()结构中没有设置inline=True标志,而且该语句没有定义明确的 returns()子句。

默认的生成条款是否“预先执行”不是通常需要考虑的事情,除非由于性能原因而被解决。

When the statement is executed with a single set of parameters (that is, it is not an “executemany” style execution), the returned ResultProxy will contain a collection accessible via ResultProxy.postfetch_cols() which contains a list of all Column objects which had an inline-executed default. Similarly, all parameters which were bound to the statement, including all Python and SQL expressions which were pre-executed, are present in the ResultProxy.last_inserted_params() or ResultProxy.last_updated_params() collections on ResultProxy. The ResultProxy.inserted_primary_key collection contains a list of primary key values for the row inserted (a list so that single-column and composite-column primary keys are represented in the same format).

服务器端默认值

SQL表达式默认的变体是Column.server_default,它在Table.create()操作期间被放置在CREATE TABLE语句中:

t = Table('test', meta,
    Column('abc', String(20), server_default='abc'),
    Column('created_at', DateTime, server_default=text("sysdate"))
)

创建上述表格的调用将产生:

CREATE TABLE test (
    abc varchar(20) default 'abc',
    created_at datetime default sysdate
)

Column.server_default的行为类似于常规的SQL默认行为;如果将其置于数据库的主键列上,但没有“后取”ID的方式,且语句不是“内联”的,则SQL表达式将被预执行;否则,SQLAlchemy会让数据库端的默认值正常启动。

触发列

可以使用FetchedValue作为标记来调出具有由数据库触发器或其他外部过程设置的值的列:

t = Table('test', meta,
    Column('abc', String(20), server_default=FetchedValue()),
    Column('def', String(20), server_onupdate=FetchedValue())
)

在0.8.0b2,0.7.10版本中更改: FetchedValue上的for_update参数在指定为server_onupdate如果使用旧版本,请将onupdate指定为server_onupdate=FetchedValue(for_update=True)

这些标记在创建表时不会发出“default”子句,但是它们将静态的server_default子句设置为相同的内部标志,为高级工具提供了一个“post-fetch “应在插入或更新后执行这些行。

注意

FetchedValue与主键列结合使用通常是不恰当的,特别是在使用ORM或其他需要ResultProxy.inserted_primary_key属性的情况下。这是因为“后取”操作要求主键值已经可用,以便可以在主键上选择该行。

对于服务器生成的主键值,所有数据库都提供特殊的访问器或其他技术来获取表的“最后插入的主键”列。这些机制不受FetchedValue的影响。对于使用触发器生成主键值的特殊情况,并且正在使用的数据库不支持RETURNING子句,可能需要放弃使用触发器,而是应用SQL表达式或函数作为“预执行”表达式:

t = Table('test', meta,
        Column('abc', MyType, default=func.generate_new_value(), primary_key=True)
)

Where above, when Table.insert() is used, the func.generate_new_value() expression will be pre-executed in the context of a scalar SELECT statement, and the new value will be applied to the subsequent INSERT, while at the same time being made available to the ResultProxy.inserted_primary_key attribute.

定义序列

SQLAlchemy使用Sequence对象表示数据库序列,这被认为是“列缺省”的特例。它只对数据库有明确的支持,其中包括Postgresql,Oracle和Firebird。Sequence对象被忽略。

The Sequence may be placed on any column as a “default” generator to be used during INSERT operations, and can also be configured to fire off during UPDATE operations if desired. 它通常与单个整数主键列结合使用:

table = Table("cartitems", meta,
    Column("cart_id", Integer, Sequence('cart_id_seq'), primary_key=True),
    Column("description", String(40)),
    Column("createdate", DateTime())
)

在上面,表“cartitems”与名为“cart_id_seq”的序列相关联。当针对“cartitems”的INSERT语句发生并且“cart_id”列没有值时,“cart_id_seq”序列将被用于生成一个值。

Sequence与表关联时,为该表发出的CREATE和DROP语句也将为该序列对象发出CREATE / DROP,从而将序列对象与其父表“绑定”。

The Sequence object also implements special functionality to accommodate Postgresql’s SERIAL datatype. PG中的SERIAL类型自动生成一个在插入过程中隐式使用的序列。这意味着如果一个Table对象在其主键列上定义了一个Sequence,这样它就可以与Oracle和Firebird一起使用,那么Sequence PG通常使用的“隐式”序列的方式。对于这个用例,将标志optional=True添加到Sequence对象 - 这表明仅当数据库提供时才应使用Sequence没有其他选项可用于生成主键标识符。

Sequence对象也可以像SQL表达式那样独立执行,具有调用其“下一个值”功能的效果:

seq = Sequence('some_sequence')
nextid = connection.execute(seq)

关联一个序列作为服务器端默认

When we associate a Sequence with a Column as above, this association is an in-Python only association. 为我们的Table生成的CREATE TABLE不会引用这个序列。如果我们希望将序列用作服务器端缺省值,即使我们从SQL命令行向表中发出INSERT命令,也可以使用Column.server_default参数与序列的值生成函数一起使用,可以从Sequence.next_value()方法获得:

cart_id_seq = Sequence('cart_id_seq')
table = Table("cartitems", meta,
    Column(
        "cart_id", Integer, cart_id_seq,
        server_default=cart_id_seq.next_value(), primary_key=True),
    Column("description", String(40)),
    Column("createdate", DateTime())
)

上面的元数据将在Postgresql上生成一个CREATE TABLE语句,如下所示:

CREATE TABLE cartitems (
    cart_id INTEGER DEFAULT nextval('cart_id_seq') NOT NULL,
    description VARCHAR(40),
    createdate TIMESTAMP WITHOUT TIME ZONE,
    PRIMARY KEY (cart_id)
)

我们把Sequence也作为一个Python方面的默认设置,即在Column定义中提到了两次。取决于正在使用的后端,这可能不是严格必要的,例如在Postgresql后端,Core将使用RETURNING访问新生成的主键值。However, for the best compatibility, Sequence was originally intended to be a Python-side directive first and foremost so it’s probably a good idea to specify it in this way as well.

默认对象API

class sqlalchemy.schema.ColumnDefault(arg, **kwargs)

基础:sqlalchemy.schema.DefaultGenerator

列上的普通默认值。

这可以对应一个常量,一个可调用的函数或一个SQL子句。

ColumnDefault is generated automatically whenever the default, onupdate arguments of Column are used. 一个ColumnDefault也可以在位置上传递。

例如,以下内容:

Column('foo', Integer, default=50)

相当于:

Column('foo', Integer, ColumnDefault(50))
class sqlalchemy.schema。 DefaultClause for_update = False _reflected = False

基础:sqlalchemy.schema.FetchedValue

DDL指定的DEFAULT列值。

DefaultClause is a FetchedValue that also generates a “DEFAULT” clause when “CREATE TABLE” is emitted.

DefaultClause is generated automatically whenever the server_default, server_onupdate arguments of Column are used. 一个DefaultClause也可以在位置上传递。

例如,以下内容:

Column('foo', Integer, server_default="50")

相当于:

Column('foo', Integer, DefaultClause("50"))
class sqlalchemy.schema.DefaultGenerator(for_update=False)

基础:sqlalchemy.schema._NotAColumnExprsqlalchemy.schema.SchemaItem

默认值的基类。

class sqlalchemy.schema.FetchedValue(for_update=False)

基础:sqlalchemy.schema._NotAColumnExprsqlalchemy.sql.expression.SchemaEventTarget

透明的数据库端默认标记。

当数据库配置为为列提供一些自动默认值时,使用FetchedValue

例如。:

Column('foo', Integer, FetchedValue())

会指出某个触发器或默认生成器将在INSERT期间为foo列创建一个新值。

也可以看看

Triggered Columns

class sqlalchemy.schema。 PassiveDefault * arg**千瓦 T5> ) T6> ¶ T7>

基础:sqlalchemy.schema.DefaultClause

DDL指定的DEFAULT列值。

从0.6版开始弃用: PassiveDefault已弃用。使用DefaultClause

class sqlalchemy.schema.Sequence(name, start=None, increment=None, minvalue=None, maxvalue=None, nominvalue=None, nomaxvalue=None, cycle=None, schema=None, optional=False, quote=None, metadata=None, quote_schema=None, for_update=False)

基础:sqlalchemy.schema.DefaultGenerator

表示一个命名的数据库序列。

Sequence对象表示数据库序列的名称和配置参数。它也代表一个可以由SQLAlchemy EngineConnection“执行”的构造,为目标数据库渲染适当的“下一个值”函数并返回结果。

Sequence通常与主键列相关联:

some_table = Table(
    'some_table', metadata,
    Column('id', Integer, Sequence('some_table_seq'),
    primary_key=True)
)

当上面的Table发出CREATE TABLE时,如果目标平台支持序列,那么也会发出CREATE SEQUENCE语句。对于不支持序列的平台,忽略Sequence结构。

__init__(name, start=None, increment=None, minvalue=None, maxvalue=None, nominvalue=None, nomaxvalue=None, cycle=None, schema=None, optional=False, quote=None, metadata=None, quote_schema=None, for_update=False)

构建一个Sequence对象。

参数:
  • 名称 - 序列的名称。
  • start – the starting index of the sequence. 将CREATE SEQUENCE命令作为“START WITH”子句的值发送到数据库时使用此值。如果None,则该子句被省略,在大多数平台上该子句表示起始值为1。
  • 增量 - 序列的增量值。将CREATE SEQUENCE命令作为“INCREMENT BY”子句的值发送到数据库时使用此值。如果None,则该子句被省略,在大多数平台上该子句表示增量1。
  • minvalue -

    序列的最小值。将CREATE SEQUENCE命令作为“MINVALUE”子句的值发送到数据库时使用此值。如果None,该子句被省略,在大多数平台上分别指示升序和降序序列的最小值为1和-2 ^ 63-1。

    版本1.0.7中的新功能

  • maxvalue -

    序列的最大值。将CREATE SEQUENCE命令作为“MAXVALUE”子句的值发送到数据库时使用此值。如果None,则省略该子句,在大多数平台上分别指示升序和降序的最大值为2 ^ 63-1和-1。

    版本1.0.7中的新功能

  • nominvalue -

    没有最小值的序列。当CREATE SEQUENCE命令作为“NO MINVALUE”子句的值发送到数据库时,使用此值。如果None,该子句被省略,在大多数平台上分别指示升序和降序序列的最小值为1和-2 ^ 63-1。

    版本1.0.7中的新功能

  • nomaxvalue -

    没有最大值的序列。将CREATE SEQUENCE命令作为“NO MAXVALUE”子句的值发送到数据库时使用此值。如果None,则省略该子句,在大多数平台上分别指示升序和降序的最大值为2 ^ 63-1和-1。

    版本1.0.7中的新功能

  • 周期 -

    当升序或降序达到最大值或最小值时,允许序列回绕。当CREATE SEQUENCE命令作为“CYCLE”子句发送到数据库时使用此值。如果达到限制,则生成的下一个数字将分别为minvalue或maxvalue。如果cycle = False(默认值),则在序列达到其最大值后调用nextval将返回一个错误。

    版本1.0.7中的新功能

  • schema – Optional schema name for the sequence, if located in a schema other than the default. MetaData出现时,选择模式名称的规则与Table.schema相同。
  • optional – boolean value, when True, indicates that this Sequence object only needs to be explicitly generated on backends that don’t provide another way to generate primary key identifiers. 目前,这基本上意味着“不要在Postgresql后端创建这个序列,SERIAL关键字会自动为我们创建一个序列”。
  • quote – boolean value, when True or False, explicitly forces quoting of the schema name on or off. 如果保留默认值None,则会发生基于大小写和保留字的正常引用规则。
  • quote_schema – set the quoting preferences for the schema name.
  • 元数据 -

    可选的MetaData对象,它将与这个Sequence关联。A Sequence that is associated with a MetaData gains access to the bind of that MetaData, meaning the Sequence.create() and Sequence.drop() methods will make usage of that engine automatically.

    Changed in version 0.7: Additionally, the appropriate CREATE SEQUENCE/ DROP SEQUENCE DDL commands will be emitted corresponding to this Sequence when MetaData.create_all() and MetaData.drop_all() are invoked.

    请注意,当一个Sequence应用于Column时,Sequence会自动与MetaData当该关联被创建时,该列的父TableThe Sequence will then be subject to automatic CREATE SEQUENCE/DROP SEQUENCE corresponding to when the Table object itself is created or dropped, rather than that of the MetaData object overall.

  • for_update – Indicates this Sequence, when associated with a Column, should be invoked for UPDATE statements on that column’s table, rather than for INSERT statements, when no value is otherwise present for that column in the statement.
create(bind=None, checkfirst=True)

在数据库中创建这个序列。

drop(bind=None, checkfirst=True)

从数据库中删除这个序列。

next_value T0> ( T1> ) T2> ¶ T3>

返回一个next_value函数元素,它将在任何SQL表达式中为这个Sequence提供适当的增量函数。