SQLAlchemy针对在INSERT和UPDATE语句期间发生的列级事件提供了非常丰富的功能集。选项包括:
所有插入/更新默认值的一般规则是,只有当特定列的值不作为execute()参数传递时才会生效。否则,使用给定的值。
最简单的默认值是一个用作列默认值的标量值:
Table("mytable", meta,
Column("somecolumn", Integer, default=12)
)上面,如果没有提供其他值,则在INSERT期间将值“12”绑定为列值。
标量值也可能与UPDATE语句相关联,尽管这不是很常见(因为UPDATE语句通常在寻找动态默认值):
Table("mytable", meta,
Column("somecolumn", Integer, onupdate=25)
)Column.default和Column.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.default和Column.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.
“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方言。implicit_returning标志设置为False。支持RETURNING的方言目前包括Postgresql,Oracle,Firebird和MS-SQL。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)当我们如上所述将Sequence与Column相关联时,此关联仅为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.
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))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"))sqlalchemy.schema。 DefaultGenerator ( for_update = False / T5> ¶ T6>基础:sqlalchemy.schema._NotAColumnExpr,sqlalchemy.schema.SchemaItem
列默认值的基类。
sqlalchemy.schema。 T1> FetchedValue T2> ( T3> FOR_UPDATE =假 T4> )< / T5> ¶ T6>基础:sqlalchemy.schema._NotAColumnExpr,sqlalchemy.sql.expression.SchemaEventTarget
透明数据库默认的标记。
当数据库配置为为列提供一些自动默认值时,使用FetchedValue。
例如。:
Column('foo', Integer, FetchedValue())将指出某个触发器或默认生成器将在INSERT期间为foo列创建新值。
也可以看看
sqlalchemy.schema。 PassiveDefault ( * arg,**千瓦 T5> ) T6> ¶ T7>基础:sqlalchemy.schema.DefaultClause
DDL指定的DEFAULT列值。
从版本0.6开始弃用: PassiveDefault已弃用。使用DefaultClause。
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 Engine或Connection执行的构造,为目标数据库呈现适当的“下一个值”函数并返回结果。
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(bind=None, checkfirst=True)¶在数据库中创建这个序列。
drop(bind=None, checkfirst=True)¶从数据库中删除这个序列。
next_value T0> ( T1> ) T2> ¶ T3>返回一个next_value函数元素,该元素将为任何SQL表达式中的Sequence提供适当的增量函数。