版本: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),
)

当update语句执行并且没有为last_updated传递值时,将执行datetime.datetime.now() Python函数并将其返回值用作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。

虽然传递给默认函数的上下文对象具有许多属性,但current_parameters成员是仅在执行默认函数时才提供的特殊成员,用于从其现有值中派生默认值。For a single statement that is executing many sets of bind parameters, the user-defined function is called for each set of parameters, and current_parameters will be provided with each individual parameter set for each execution.

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语句时“inline”执行,也就是说,执行一条语句,将给定的表达式或子查询嵌入到语句的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()子句。

除非出于性能考虑,否则默认生成子句“预执行”不是通常需要考虑的事项。

当使用一组参数执行语句(即,它不是“executemany”样式执行)时,返回的ResultProxy将包含可通过ResultProxy.postfetch_cols()其中包含具有内联执行的缺省值的所有Column对象的列表。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. ResultProxy.inserted_primary_key集合包含插入行的主键值列表(列表使得单列和组合列主键以相同的格式表示)。

服务器端默认值

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属性的任何其他场景时。这是因为“post-fetch”操作要求主键值已经可用,以便可以在主键上选择该行。

对于服务器生成的主键值,所有数据库都提供特殊的访问器或其他技术来获取表的“最后插入的主键”列。这些机制不受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对象被忽略。

Sequence可以作为INSERT操作期间使用的“默认”生成器放置在任何列上,也可以配置为在UPDATE操作期间根据需要触发。它通常与单个整数主键列结合使用:

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,从而将序列对象与其父表“捆绑”。

Sequence对象还实现了特殊的功能以适应Postgresql的SERIAL数据类型。PG中的SERIAL类型自动生成一个在插入过程中隐式使用的序列。这意味着如果一个Table对象在其主键列上定义了一个Sequence,以便它可以与Oracle和Firebird一起使用,那么Sequence将进入PG通常使用的“隐式”序列的方式。对于这个用例,将标志optional=True添加到Sequence对象 - 这表明仅当数据库提供时才应使用Sequence没有其他选项可用于生成主键标识符。

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

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

将序列关联到服务器端默认

当我们如上所述将SequenceColumn相关联时,此关联仅为in-Python only关联。将为我们的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 T5> ) T6> ¶ T7>

基础: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(arg, 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 / T5> ¶ T6>

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

默认值的基类。

类 T0> sqlalchemy.schema。 T1> FetchedValue T2> ( T3> FOR_UPDATE =假 T4> )< / T5> ¶ T6>

基础: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对象。

参数:
  • 名称 - 序列的名称。
  • 开始 - 序列的起始索引。当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.

    版本0.7更改:此外,当MetaData.create_all()时,相应的Sequence将会发出相应的CREATE SEQUENCE / DROP SEQUENCE DDL命令和MetaData.drop_all()被调用。

    请注意,当一个Sequence应用于Column时,Sequence会自动与该元素的MetaData对象关联列的父Table,当该关联时。The 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提供适当的增量函数。