associationproxy
用于跨关系创建目标属性的读/写视图。它本质上隐藏了在两个端点之间使用“middle”属性,并可用于从相关对象集合中挑选字段,或减少使用关联对象模式的冗长性。通过创造性地应用,关联代理允许构建几乎所有几何图形的复杂集合和字典视图,并使用标准的、透明配置的关系模式持久化到数据库中。
考虑两个类之间的多对多映射, User
和 Keyword
.每个 User
可以有任何数量的 Keyword
对象,反之亦然(多对多模式在 多对多 ):
from sqlalchemy import Column, Integer, String, ForeignKey, Table
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
kw = relationship("Keyword", secondary=lambda: userkeywords_table)
def __init__(self, name):
self.name = name
class Keyword(Base):
__tablename__ = 'keyword'
id = Column(Integer, primary_key=True)
keyword = Column('keyword', String(64))
def __init__(self, keyword):
self.keyword = keyword
userkeywords_table = Table('userkeywords', Base.metadata,
Column('user_id', Integer, ForeignKey("user.id"),
primary_key=True),
Column('keyword_id', Integer, ForeignKey("keyword.id"),
primary_key=True)
)
读取和操作与 User
需要从每个集合元素遍历到 .keyword
属性,这可能会很尴尬:
>>> user = User('jek')
>>> user.kw.append(Keyword('cheese inspector'))
>>> print(user.kw)
[<__main__.Keyword object at 0x12bf830>]
>>> print(user.kw[0].keyword)
cheese inspector
>>> print([keyword.keyword for keyword in user.kw])
['cheese inspector']
这个 association_proxy
应用于 User
类生成的“视图” kw
关系,它只公开 .keyword
与每个 Keyword
对象:
from sqlalchemy.ext.associationproxy import association_proxy
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
kw = relationship("Keyword", secondary=lambda: userkeywords_table)
def __init__(self, name):
self.name = name
# proxy the 'keyword' attribute from the 'kw' relationship
keywords = association_proxy('kw', 'keyword')
我们现在可以参考 .keywords
集合作为字符串列表,既可读又可写。新的 Keyword
对象是透明地为我们创建的:
>>> user = User('jek')
>>> user.keywords.append('cheese inspector')
>>> user.keywords
['cheese inspector']
>>> user.keywords.append('snack ninja')
>>> user.kw
[<__main__.Keyword object at 0x12cdd30>, <__main__.Keyword object at 0x12cde30>]
这个 AssociationProxy
对象由 association_proxy()
函数是 Python descriptor . 无论是声明性映射还是通过 mapper()
使用函数。
代理通过对底层映射属性或集合进行操作来响应操作,以及通过代理所做的更改,在映射属性中立即可见,反之亦然。基础属性保持完全可访问。
首次访问时,关联代理对目标集合执行自省操作,以便其行为正确对应。详细信息,例如本地代理属性是集合(通常是这样)还是标量引用,以及集合的行为是否类似于集合、列表或字典,以便代理的行为与基础集合或属性的行为相同。
当关联代理截获一个list append()事件(或set add()、dictionary_u setitem_uuuu()或scalar assignment事件)时,它使用其构造函数实例化一个“中间”对象的新实例,将给定值作为单个参数传递。在上面的示例中,一个操作如下:
user.keywords.append('cheese inspector')
由关联代理转换为操作::
user.kw.append(Keyword('cheese inspector'))
这个例子在这里有效,因为我们已经为 Keyword
接受一个位置参数, keyword
. 对于单参数构造函数不可行的情况,可以使用 creator
参数,它引用一个可调用的(即python函数),该函数将在给定奇异参数的情况下生成一个新的对象实例。下面我们使用lambda来说明这一点,这是典型的:
class User(Base):
# ...
# use Keyword(keyword=kw) on append() events
keywords = association_proxy('kw', 'keyword',
creator=lambda kw: Keyword(keyword=kw))
这个 creator
函数在基于列表或集合的集合或标量属性的情况下接受单个参数。对于基于字典的集合,它接受两个参数“key”和“value”。下面的示例 代理到基于字典的集合 .
“关联对象”模式是多对多关系的一种扩展形式,其描述如下: 关联对象 . 关联代理对于在正常使用期间防止“关联对象”妨碍使用非常有用。
假设我们 userkeywords
上面的表有一些额外的列,我们希望显式映射这些列,但在大多数情况下,我们不需要直接访问这些属性。下面,我们演示了一个新的映射,它介绍了 UserKeyword
类,它映射到 userkeywords
表如前所示。此类添加了一个附加列 special_key
,我们偶尔想要访问的值,但在通常情况下不是。我们在 User
类称为 keywords
这将弥补 user_keywords
收藏 User
到 .keyword
每个属性都存在 UserKeyword
::
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
# association proxy of "user_keywords" collection
# to "keyword" attribute
keywords = association_proxy('user_keywords', 'keyword')
def __init__(self, name):
self.name = name
class UserKeyword(Base):
__tablename__ = 'user_keyword'
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
keyword_id = Column(Integer, ForeignKey('keyword.id'), primary_key=True)
special_key = Column(String(50))
# bidirectional attribute/collection of "user"/"user_keywords"
user = relationship(User,
backref=backref("user_keywords",
cascade="all, delete-orphan")
)
# reference to the "Keyword" object
keyword = relationship("Keyword")
def __init__(self, keyword=None, user=None, special_key=None):
self.user = user
self.keyword = keyword
self.special_key = special_key
class Keyword(Base):
__tablename__ = 'keyword'
id = Column(Integer, primary_key=True)
keyword = Column('keyword', String(64))
def __init__(self, keyword):
self.keyword = keyword
def __repr__(self):
return 'Keyword(%s)' % repr(self.keyword)
通过上述配置,我们可以在 .keywords
每个的集合 User
对象,以及 UserKeyword
隐蔽:
>>> user = User('log')
>>> for kw in (Keyword('new_from_blammo'), Keyword('its_big')):
... user.keywords.append(kw)
...
>>> print(user.keywords)
[Keyword('new_from_blammo'), Keyword('its_big')]
在上面,每个 .keywords.append()
操作等效于:
>>> user.user_keywords.append(UserKeyword(Keyword('its_heavy')))
这个 UserKeyword
关联对象在这里有两个填充的属性;关联对象 .keyword
由于传递 Keyword
对象作为第一个参数。这个 .user
然后将参数指定为 UserKeyword
对象附加到 User.user_keywords
集合,其中双向关系配置在 User.user_keywords
和 UserKeyword.user
结果在一个群体中 UserKeyword.user
属性。这个 special_key
上面的参数的默认值为 None
.
在我们想要的情况下 special_key
为了有价值,我们创造 UserKeyword
对象。下面我们将分配所有三个属性,其中 .user
具有 UserKeyword
被附加到 User.user_keywords
收藏:
>>> UserKeyword(Keyword('its_wood'), user, special_key='my special key')
关联代理向我们返回 Keyword
所有这些操作表示的对象:
>>> user.keywords
[Keyword('new_from_blammo'), Keyword('its_big'), Keyword('its_heavy'), Keyword('its_wood')]
关联代理也可以代理到基于字典的集合。SQLAlchemy映射通常使用 attribute_mapped_collection()
用于创建字典集合的集合类型,以及中描述的扩展技术 自定义基于词典的集合 .
关联代理在检测到基于字典的集合的使用时调整其行为。当新值添加到字典中时,关联代理通过将两个参数传递给创建函数而不是一个参数(键和值)来实例化中间对象。和往常一样,这个创建函数默认为中间类的构造函数,并且可以使用 creator
争论。
下面,我们修改了 UserKeyword
示例如下: User.user_keywords
现在将使用字典映射集合,其中 UserKeyword.special_key
参数将用作字典的键。然后我们应用 creator
论据 User.keywords
代理,以便在将新元素添加到字典时适当地分配这些值::
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.collections import attribute_mapped_collection
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
# proxy to 'user_keywords', instantiating UserKeyword
# assigning the new key to 'special_key', values to
# 'keyword'.
keywords = association_proxy('user_keywords', 'keyword',
creator=lambda k, v:
UserKeyword(special_key=k, keyword=v)
)
def __init__(self, name):
self.name = name
class UserKeyword(Base):
__tablename__ = 'user_keyword'
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
keyword_id = Column(Integer, ForeignKey('keyword.id'), primary_key=True)
special_key = Column(String)
# bidirectional user/user_keywords relationships, mapping
# user_keywords with a dictionary against "special_key" as key.
user = relationship(User, backref=backref(
"user_keywords",
collection_class=attribute_mapped_collection("special_key"),
cascade="all, delete-orphan"
)
)
keyword = relationship("Keyword")
class Keyword(Base):
__tablename__ = 'keyword'
id = Column(Integer, primary_key=True)
keyword = Column('keyword', String(64))
def __init__(self, keyword):
self.keyword = keyword
def __repr__(self):
return 'Keyword(%s)' % repr(self.keyword)
我们举例说明 .keywords
集合作为字典,映射 UserKeyword.string_key
价值到 Keyword
对象::
>>> user = User('log')
>>> user.keywords['sk1'] = Keyword('kw1')
>>> user.keywords['sk2'] = Keyword('kw2')
>>> print(user.keywords)
{'sk1': Keyword('kw1'), 'sk2': Keyword('kw2')}
在前面的示例中,从关系代理到标量属性、跨关联对象代理和代理字典,我们可以将这三种技术结合起来 User
一 keywords
严格处理字符串值的字典 special_key
映射到字符串 keyword
. 两个 UserKeyword
和 Keyword
课程是完全隐藏的。这是通过在上建立关联代理来实现的 User
指出现在 UserKeyword
::
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm.collections import attribute_mapped_collection
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
name = Column(String(64))
# the same 'user_keywords'->'keyword' proxy as in
# the basic dictionary example
keywords = association_proxy(
'user_keywords',
'keyword',
creator=lambda k, v:
UserKeyword(special_key=k, keyword=v)
)
def __init__(self, name):
self.name = name
class UserKeyword(Base):
__tablename__ = 'user_keyword'
user_id = Column(Integer, ForeignKey('user.id'), primary_key=True)
keyword_id = Column(Integer, ForeignKey('keyword.id'),
primary_key=True)
special_key = Column(String)
user = relationship(User, backref=backref(
"user_keywords",
collection_class=attribute_mapped_collection("special_key"),
cascade="all, delete-orphan"
)
)
# the relationship to Keyword is now called
# 'kw'
kw = relationship("Keyword")
# 'keyword' is changed to be a proxy to the
# 'keyword' attribute of 'Keyword'
keyword = association_proxy('kw', 'keyword')
class Keyword(Base):
__tablename__ = 'keyword'
id = Column(Integer, primary_key=True)
keyword = Column('keyword', String(64))
def __init__(self, keyword):
self.keyword = keyword
User.keywords
现在是字符串到字符串的字典,其中 UserKeyword
和 Keyword
使用关联代理为我们透明地创建和删除对象。在下面的示例中,我们演示了赋值运算符的用法,它也是由关联代理适当处理的,可以立即将字典值应用于集合:
>>> user = User('log')
>>> user.keywords = {
... 'sk1':'kw1',
... 'sk2':'kw2'
... }
>>> print(user.keywords)
{'sk1': 'kw1', 'sk2': 'kw2'}
>>> user.keywords['sk3'] = 'kw3'
>>> del user.keywords['sk2']
>>> print(user.keywords)
{'sk1': 'kw1', 'sk3': 'kw3'}
>>> # illustrate un-proxied usage
... print(user.user_keywords['sk3'].kw)
<__main__.Keyword object at 0x12ceb90>
我们上面的例子有一个警告,那是因为 Keyword
对象是为每个字典集操作创建的,该示例无法保持 Keyword
对象的字符串名称,这是标记场景(如本场景)的典型要求。对于这个用例,方法 UniqueObject 或类似的创新策略,建议将“先查找,然后创建”策略应用于 Keyword
类,以便 Keyword
如果给定的名称已经存在,则返回。
这个 AssociationProxy
特点是简单的SQL构造功能,与底层相关 relationship()
以及目标属性。例如, RelationshipProperty.Comparator.any()
和 RelationshipProperty.Comparator.has()
操作可用,并将生成“嵌套的”exists子句,例如在我们的基本关联对象示例中:
>>> print(session.query(User).filter(User.keywords.any(keyword='jek')))
SELECT user.id AS user_id, user.name AS user_name
FROM user
WHERE EXISTS (SELECT 1
FROM user_keyword
WHERE user.id = user_keyword.user_id AND (EXISTS (SELECT 1
FROM keyword
WHERE keyword.id = user_keyword.keyword_id AND keyword.keyword = :keyword_1)))
对于标量属性的代理, __eq__()
支持:
>>> print(session.query(UserKeyword).filter(UserKeyword.keyword == 'jek'))
SELECT user_keyword.*
FROM user_keyword
WHERE EXISTS (SELECT 1
FROM keyword
WHERE keyword.id = user_keyword.keyword_id AND keyword.keyword = :keyword_1)
和 .contains()
可用于标量集合的代理:
>>> print(session.query(User).filter(User.keywords.contains('jek')))
SELECT user.*
FROM user
WHERE EXISTS (SELECT 1
FROM userkeywords, keyword
WHERE user.id = userkeywords.user_id
AND keyword.id = userkeywords.keyword_id
AND keyword.keyword = :keyword_1)
AssociationProxy
Query.join()
有点手动使用 attr
星型参数上下文中的属性:
q = session.query(User).join(*User.keywords.attr)
attr
是由 AssociationProxy.local_attr
和 AssociationProxy.remote_attr
,它只是实际代理属性的同义词,也可用于查询::
uka = aliased(UserKeyword)
ka = aliased(Keyword)
q = session.query(User).\
join(uka, User.keywords.local_attr).\
join(ka, User.keywords.remote_attr)
1.3 新版功能.
给定映射为:
class A(Base):
__tablename__ = 'test_a'
id = Column(Integer, primary_key=True)
ab = relationship(
'AB', backref='a', uselist=False)
b = association_proxy(
'ab', 'b', creator=lambda b: AB(b=b),
cascade_scalar_deletes=True)
class B(Base):
__tablename__ = 'test_b'
id = Column(Integer, primary_key=True)
ab = relationship('AB', backref='b', cascade='all, delete-orphan')
class AB(Base):
__tablename__ = 'test_ab'
a_id = Column(Integer, ForeignKey(A.id), primary_key=True)
b_id = Column(Integer, ForeignKey(B.id), primary_key=True)
对…的委托 A.b
将生成一个 AB
对象:
a.b = B()
这个 A.b
关联是标量的,包括对标志的使用 AssociationProxy.cascade_scalar_deletes
. 设置时,设置 A.b
到 None
将移除 A.ab
也::
a.b = None
assert a.ab is None
什么时候? AssociationProxy.cascade_scalar_deletes
未设置,关联对象 a.ab
以上将保持不变。
请注意,这不是基于集合的关联代理的行为;在这种情况下,当移除代理集合的成员时,始终移除中间关联对象。是否删除行取决于关系级联设置。
参见
sqlalchemy.ext.associationproxy.
association_proxy
(target_collection, attr, **kw)¶返回一个python属性,该属性实现一个目标属性的视图,该视图引用目标成员上的属性。
返回的值是的实例 AssociationProxy
.
实现一个python属性,将关系表示为简单值或标量值的集合。代理属性将模拟目标的集合类型(list、dict或set),或者在一对一关系的情况下,模拟简单的标量值。
target_collection¶ -- 将代理到的属性的名称。此属性通常由 relationship()
链接到目标集合,但也可以是多对一或非标量关系。
attr¶ -- 我们将代理的一个或多个关联实例的属性。例如,给定一个目标集合 [Obj1,Obj2] ,此代理属性创建的列表如下 [getattr(obj1, attr), getattr(obj2, attr)] 如果关系是一对一或其他uselist=false,那么只需:getattr(obj, attr )
creator¶ -- 可选的。将新项添加到此代理集合时,将创建由目标集合收集的类的新实例。对于列表和集合集合,将使用新实例的“value”调用目标类构造函数。对于dict类型,传递两个参数:key和value。如果要以不同的方式构造实例,请提供 造物主 函数,它接受上述参数并返回实例。对于标量关系,如果目标为“无”,则将调用creator()。如果目标存在,则在关联的对象上将set操作代理为setattr()。如果有一个具有多个属性的关联对象,则可以设置映射到不同属性的多个关联代理。有关示例,请参见单元测试,以及有关如何使用creator()函数在这种情况下按需构造标量关系的示例。
**kw¶ -- 将任何其他关键字参数传递给 AssociationProxy
.
sqlalchemy.ext.associationproxy.
AssociationProxy
(target_collection, attr, creator=None, getset_factory=None, proxy_factory=None, proxy_bulk_set=None, info=None, cascade_scalar_deletes=False)¶基地: sqlalchemy.orm.base.InspectionAttrInfo
表示对象属性的读/写视图的描述符。
__eq__
¶继承 __eq__
属性 object
返回self==值。
__init__
(target_collection, attr, creator=None, getset_factory=None, proxy_factory=None, proxy_bulk_set=None, info=None, cascade_scalar_deletes=False)¶构建新的 AssociationProxy
.
这个 association_proxy()
不过,函数在这里作为通常的入口点提供 AssociationProxy
可以直接实例化和/或子类化。
target_collection¶ -- 我们要代理的集合的名称,通常使用 relationship()
.
attr¶ -- 我们将代理的已收集实例的属性。例如,给定一个目标集合 [Obj1,Obj2] ,此代理属性创建的列表如下 [getattr(obj1,attr),getattr(obj2,attr)]
creator¶ -- 可选的。将新项添加到此代理集合时,将创建由目标集合收集的类的新实例。对于列表和集合集合,将使用新实例的“value”调用目标类构造函数。对于dict类型,传递两个参数:key和value。如果要以不同的方式构造实例,请提供一个“creator”函数,该函数接受上述参数并返回实例。
cascade_scalar_deletes¶ -- 如果为真,则指示将代理值设置为 None
,或通过删除 del
,还应删除源对象。仅适用于标量属性。通常,删除代理目标不会删除代理源,因为此对象可能具有其他仍要保留的状态。…添加的版本:1.3..参阅: 级联标量删除 -完整用法示例
getset_factory¶ -- 可选的。代理属性访问由基于 attr 此代理的参数。如果要自定义此行为,可以提供 getset_factory 可调用,产生一个元组 getter 和 setter 功能。使用两个参数调用工厂,即基础集合的抽象类型和此代理实例。
proxy_factory¶ -- 可选的。要模拟的集合类型是通过嗅探目标集合来确定的。如果您的集合类型不能通过duck类型来确定,或者您希望使用不同的集合实现,那么您可以提供一个工厂函数来生成这些集合。仅适用于非标量关系。
proxy_bulk_set¶ -- 可选,与代理工厂一起使用。有关详细信息,请参阅_set()方法。
info¶ -- 可选,将分配给 AssociationProxy.info
如果存在。…添加的版本:1.0.9
__le__
¶继承 __le__
属性 object
返回self<=value。
__lt__
¶继承 __lt__
属性 object
返回self<value。
__ne__
¶继承 __ne__
属性 object
回归自我!=值。
extension_type
= symbol('ASSOCIATION_PROXY')¶for_class
(class_, obj=None)¶返回特定映射类的本地内部状态。
例如,给一个班 User
::
class User(Base):
# ...
keywords = association_proxy('kws', 'keyword')
如果我们访问这个 AssociationProxy
从 Mapper.all_orm_descriptors
,我们希望查看由映射的此代理的目标类 User
::
inspect(User).all_orm_descriptors["keywords"].for_class(User).target_class
这将返回 AssociationProxyInstance
这是特定于 User
班级。这个 AssociationProxy
对象仍不可知其父类。
1.3 新版功能: - AssociationProxy
no longer stores
any state specific to a particular parent class; the state is now
stored in per-class AssociationProxyInstance
objects.
info
¶继承 info
属性 InspectionAttrInfo
与对象关联的信息字典,允许用户定义的数据与此关联 InspectionAttr
.
字典在第一次访问时生成。或者,可以将其指定为 column_property()
, relationship()
或 composite()
功能。
在 1.0.0 版更改: MapperProperty.info
也可以通过 InspectionAttrInfo.info
属性,以便它可以应用于更广泛的ORM和扩展构造。
is_aliased_class
= False¶is_attribute
= False¶is_clause_element
= False¶is_instance
= False¶is_mapper
= False¶is_property
= False¶is_selectable
= False¶sqlalchemy.ext.associationproxy.
AssociationProxyInstance
(parent, owning_class, target_class, value_attr)¶为特定于类和对象的结果提供服务的每个类对象。
这是由 AssociationProxy
当它以一个特定的类或类的实例来调用时,即当它被用作一个常规的Python描述符时。
当提到 AssociationProxy
作为普通的python描述符, AssociationProxyInstance
是实际服务于信息的对象。在正常情况下,其存在是透明的:
>>> User.keywords.scalar
False
在特殊情况下, AssociationProxy
正在直接访问对象,以便对 AssociationProxyInstance
使用 AssociationProxy.for_class()
方法:
proxy_state = inspect(User).all_orm_descriptors["keywords"].for_class(User)
# view if proxy object is scalar or not
>>> proxy_state.scalar
False
1.3 新版功能.
__eq__
¶继承 __eq__
属性 object
返回self==值。
__le__
¶继承 __le__
属性 object
返回self<=value。
__lt__
¶继承 __lt__
属性 object
返回self<value。
__ne__
¶继承 __ne__
属性 object
回归自我!=值。
any
(criterion=None, **kwargs)¶使用exists生成代理的“any”表达式。
此表达式将是使用 RelationshipProperty.Comparator.any()
和/或 RelationshipProperty.Comparator.has()
基本代理属性的运算符。
attr
¶返回的元组 (local_attr, remote_attr)
.
当使用 Query.join()
两种关系:
sess.query(Parent).join(*Parent.proxied.attr)
delete
(obj)¶for_proxy
(parent, owning_class, parent_instance)¶get
(obj)¶has
(criterion=None, **kwargs)¶使用exists生成代理的“has”表达式。
此表达式将是使用 RelationshipProperty.Comparator.any()
和/或 RelationshipProperty.Comparator.has()
基本代理属性的运算符。
info
¶local_attr
¶“本地” MapperProperty
引用人: AssociationProxyInstance
.
remote_attr
¶“遥控器” MapperProperty
引用人: AssociationProxyInstance
.
…
:attr:`.AssociationProxyInstance.attr`
:attr:`.AssociationProxyInstance.local_attr`
scalar
¶返回 True
如果这样 AssociationProxyInstance
在本地端代理一个标量关系。
set
(obj, values)¶target_class
= None¶这个处理的中介类 AssociationProxyInstance
.
截获的append/set/assignment事件将导致生成此类的新实例。
sqlalchemy.ext.associationproxy.
ObjectAssociationProxyInstance
(parent, owning_class, target_class, value_attr)¶基地: sqlalchemy.ext.associationproxy.AssociationProxyInstance
一个 AssociationProxyInstance
以对象为目标的。
__le__
¶继承 __le__
属性 object
返回self<=value。
__lt__
¶继承 __lt__
属性 object
返回self<value。
any
(criterion=None, **kwargs)¶使用exists生成代理的“any”表达式。
此表达式将是使用 RelationshipProperty.Comparator.any()
和/或 RelationshipProperty.Comparator.has()
基本代理属性的运算符。
attr
¶继承 attr
属性 AssociationProxyInstance
返回的元组 (local_attr, remote_attr)
.
当使用 Query.join()
两种关系:
sess.query(Parent).join(*Parent.proxied.attr)
contains
(obj)¶使用exists生成代理的“contains”表达式。
此表达式将是使用 RelationshipProperty.Comparator.any()
, RelationshipProperty.Comparator.has()
和/或 RelationshipProperty.Comparator.contains()
基本代理属性的运算符。
has
(criterion=None, **kwargs)¶使用exists生成代理的“has”表达式。
此表达式将是使用 RelationshipProperty.Comparator.any()
和/或 RelationshipProperty.Comparator.has()
基本代理属性的运算符。
local_attr
¶“本地” MapperProperty
引用人: AssociationProxyInstance
.
remote_attr
¶“遥控器” MapperProperty
引用人: AssociationProxyInstance
.
…
:attr:`.AssociationProxyInstance.attr`
:attr:`.AssociationProxyInstance.local_attr`
scalar
¶返回 True
如果这样 AssociationProxyInstance
在本地端代理一个标量关系。
sqlalchemy.ext.associationproxy.
ColumnAssociationProxyInstance
(parent, owning_class, target_class, value_attr)¶基地: sqlalchemy.sql.operators.ColumnOperators
, sqlalchemy.ext.associationproxy.AssociationProxyInstance
一个 AssociationProxyInstance
以数据库列为目标的。
__le__
(other)¶继承 __le__()
方法 ColumnOperators
实施 <=
操作符。
在列上下文中,生成子句 a <= b
.
__lt__
(other)¶继承 __lt__()
方法 ColumnOperators
实施 <
操作符。
在列上下文中,生成子句 a < b
.
__ne__
(other)¶继承 __ne__()
方法 ColumnOperators
实施 !=
操作符。
在列上下文中,生成子句 a != b
. 如果目标是 None
生产 a IS NOT NULL
.
all_
()¶继承 all_()
方法 ColumnOperators
产生一个 all_()
针对父对象的子句。
此运算符仅适用于标量子查询对象,或某些后端的列表达式适用于数组类型,例如::
# postgresql '5 = ALL (somearray)'
expr = 5 == mytable.c.somearray.all_()
# mysql '5 = ALL (SELECT value FROM table)'
expr = 5 == select([table.c.value]).as_scalar().all_()
1.1 新版功能.
any
(criterion=None, **kwargs)¶使用exists生成代理的“any”表达式。
此表达式将是使用 RelationshipProperty.Comparator.any()
和/或 RelationshipProperty.Comparator.has()
基本代理属性的运算符。
any_
()¶继承 any_()
方法 ColumnOperators
产生一个 any_()
针对父对象的子句。
此运算符仅适用于标量子查询对象,或某些后端的列表达式适用于数组类型,例如::
# postgresql '5 = ANY (somearray)'
expr = 5 == mytable.c.somearray.any_()
# mysql '5 = ANY (SELECT value FROM table)'
expr = 5 == select([table.c.value]).as_scalar().any_()
1.1 新版功能.
asc
()¶继承 asc()
方法 ColumnOperators
产生一个 asc()
针对父对象的子句。
attr
¶继承 attr
属性 AssociationProxyInstance
返回的元组 (local_attr, remote_attr)
.
当使用 Query.join()
两种关系:
sess.query(Parent).join(*Parent.proxied.attr)
between
(cleft, cright, symmetric=False)¶继承 between()
方法 ColumnOperators
产生一个 between()
在给定上下限的情况下,针对父对象的子句。
bool_op
(opstring, precedence=0)¶返回自定义布尔运算符。
这个方法是调用 Operators.op()
并通过 Operators.op.is_comparison
标记为真。
1.2.0b3 新版功能.
collate
(collation)¶继承 collate()
方法 ColumnOperators
产生一个 collate()
在给定排序规则字符串的情况下,对父对象执行子句。
参见
concat
(other)¶继承 concat()
方法 ColumnOperators
实现“concat”运算符。
在列上下文中,生成子句 a || b
或使用 concat()
mysql上的操作符。
contains
(other, **kwargs)¶继承 contains()
方法 ColumnOperators
实现“contains”运算符。
生成一个类似表达式,该表达式根据字符串值中间的匹配项进行测试:
column LIKE '%' || <other> || '%'
例如。::
stmt = select([sometable]).\
where(sometable.c.column.contains("foobar"))
因为操作符使用 LIKE
,通配符 "%"
和 "_"
存在于<other>表达式中的也将表现为通配符。对于文本字符串值, ColumnOperators.contains.autoescape
标志可以设置为 True
将转义应用于字符串值中出现的这些字符,以便它们与自身匹配,而不是作为通配符匹配。或者, ColumnOperators.contains.escape
参数将建立一个给定字符作为转义字符,当目标表达式不是文本字符串时可以使用该字符。
other¶ -- 要比较的表达式。这通常是一个纯字符串值,但也可以是任意的SQL表达式。类似通配符 %
和 _
默认情况下不转义,除非 ColumnOperators.contains.autoescape
标志设置为真。
autoescape¶ -- 布尔值;如果为true,则在like表达式中建立转义符,然后将其应用于 "%"
, "_"
以及转义符本身在比较值中,该值被假定为文本字符串而不是SQL表达式。表达式如::somecolumn.contains(“foo%bar”,autoescape=true)将呈现为::somecolumn,如“%”。|| :param || '%' ESCAPE '/' With the value of :param as "foo/%bar"
. .. versionadded:: 1.2 .. versionchanged:: 1.2.0 The ColumnOperators.contains.autoescape
参数现在是一个简单的布尔值而不是一个字符;转义字符本身也被转义,并默认为正斜杠,可以使用 ColumnOperators.contains.escape
参数。
escape¶ -- 一个字符,当给定时将用 ESCAPE
关键字将该字符建立为转义字符。然后可以将此字符置于 %
和 _
允许它们充当自己而不是通配符。表达式如::somecolumn.contains(“foo/%bar”,escape=“^”)将呈现为::somecolumn,如“%”。|| :param || '%' ESCAPE '^' The parameter may also be combined with ColumnOperators.contains.autoescape
::someColumn.contains(“foo%bar^bat”,escape=“^”,autoescape=true),其中,给定的文本参数将转换为 "foo^%bar^^bat"
在被传递到数据库之前。
desc
()¶继承 desc()
方法 ColumnOperators
产生一个 desc()
针对父对象的子句。
distinct
()¶继承 distinct()
方法 ColumnOperators
产生一个 distinct()
针对父对象的子句。
endswith
(other, **kwargs)¶继承 endswith()
方法 ColumnOperators
实现“endswith”运算符。
生成一个类似表达式,该表达式根据字符串值末尾的匹配项进行测试:
column LIKE '%' || <other>
例如。::
stmt = select([sometable]).\
where(sometable.c.column.endswith("foobar"))
因为操作符使用 LIKE
,通配符 "%"
和 "_"
存在于<other>表达式中的也将表现为通配符。对于文本字符串值, ColumnOperators.endswith.autoescape
标志可以设置为 True
将转义应用于字符串值中出现的这些字符,以便它们与自身匹配,而不是作为通配符匹配。或者, ColumnOperators.endswith.escape
参数将建立一个给定字符作为转义字符,当目标表达式不是文本字符串时可以使用该字符。
other¶ -- 要比较的表达式。这通常是一个纯字符串值,但也可以是任意的SQL表达式。类似通配符 %
和 _
默认情况下不转义,除非 ColumnOperators.endswith.autoescape
标志设置为真。
autoescape¶ -- 布尔值;如果为true,则在like表达式中建立转义符,然后将其应用于 "%"
, "_"
以及转义符本身在比较值中,该值被假定为文本字符串而不是SQL表达式。表达式如::somecolumn.endswith(“foo%bar”,autoescape=true)将呈现为::somecolumn,如“%”。|| :param ESCAPE '/' With the value of :param as "foo/%bar"
. .. versionadded:: 1.2 .. versionchanged:: 1.2.0 The ColumnOperators.endswith.autoescape
参数现在是一个简单的布尔值而不是一个字符;转义字符本身也被转义,并默认为正斜杠,可以使用 ColumnOperators.endswith.escape
参数。
escape¶ -- 一个字符,当给定时将用 ESCAPE
关键字将该字符建立为转义字符。然后可以将此字符置于 %
和 _
允许它们充当自己而不是通配符。表达式如::somecolumn.endswith(“foo/%bar”,escape=“^”)将呈现为::somecolumn,如“%”。|| :param ESCAPE '^' The parameter may also be combined with ColumnOperators.endswith.autoescape
::someColumn.endsWith(“foo%bar^bat”,escape=“^”,autoescape=true),其中,给定的文本参数将转换为 "foo^%bar^^bat"
在被传递到数据库之前。
has
(criterion=None, **kwargs)¶使用exists生成代理的“has”表达式。
此表达式将是使用 RelationshipProperty.Comparator.any()
和/或 RelationshipProperty.Comparator.has()
基本代理属性的运算符。
ilike
(other, escape=None)¶继承 ilike()
方法 ColumnOperators
实施 ilike
运算符,例如不区分大小写的like。
在列上下文中,生成以下任一形式的表达式:
lower(a) LIKE lower(other)
或者在支持ilike运算符的后端:
a ILIKE other
例如。::
stmt = select([sometable]).\
where(sometable.c.column.ilike("%foobar%"))
in_
(other)¶继承 in_()
方法 ColumnOperators
实施 in
操作符。
在列上下文中,生成子句 column IN <other>
.
给定参数 other
可能是:
文字值列表,例如:
stmt.where(column.in_([1, 2, 3]))
在此调用表单中,项目列表将转换为一组与给定列表长度相同的绑定参数:
WHERE COL IN (?, ?, ?)
空列表,例如:
stmt.where(column.in_([]))
在此调用形式中,表达式呈现“false”表达式,例如:
WHERE 1 != 1
这个“假”表达式在旧的sqlAlchemy版本中历史上有不同的行为,请参见 create_engine.empty_in_strategy
对于行为选项。
在 1.2 版更改: 简化了“空入”表达式的行为
绑定参数,例如 bindparam()
,如果包含 bindparam.expanding
标志:
stmt.where(column.in_(bindparam('value', expanding=True)))
在此调用表单中,表达式呈现一个特殊的非SQL占位符表达式,其外观如下:
WHERE COL IN ([EXPANDING_value])
此占位符表达式在语句执行时被截取,以便转换为前面所示的绑定参数表单的变量号。如果语句的执行方式为:
connection.execute(stmt, {"value": [1, 2, 3]})
将为数据库传递每个值的绑定参数:
WHERE COL IN (?, ?, ?)
1.2 新版功能: 添加了“扩展”绑定参数
如果传递空列表,将呈现一个特定于正在使用的数据库的特殊“空列表”表达式。在sqlite上:
WHERE COL IN (SELECT 1 FROM (SELECT 1) WHERE 1!=1)
1.3 新版功能: “expanding”绑定参数现在支持空列表
一 select()
构造,通常是相关的标量选择:
stmt.where(
column.in_(
select([othertable.c.y]).
where(table.c.x == othertable.c.x)
)
)
在这个调用表单中, ColumnOperators.in_()
按给定呈现:
WHERE COL IN (SELECT othertable.y
FROM othertable WHERE othertable.x = table.x)
other¶ -- 文字列表,a select()
构造,或 bindparam()
构造,包括 bindparam.expanding
标志设置为真。
is_
(other)¶继承 is_()
方法 ColumnOperators
实施 IS
操作符。
通常情况下, IS
与以下值比较时自动生成 None
,决定 NULL
. 但是,明确使用 IS
如果与某些平台上的布尔值进行比较,可能是可取的。
is_distinct_from
(other)¶实施 IS DISTINCT FROM
操作符。
在大多数平台上呈现“a与b不同”;在某些平台上,例如sqlite可能呈现“a不是b”。
1.1 新版功能.
isnot
(other)¶继承 isnot()
方法 ColumnOperators
实施 IS NOT
操作符。
通常情况下, IS NOT
与以下值比较时自动生成 None
,决定 NULL
. 但是,明确使用 IS NOT
如果与某些平台上的布尔值进行比较,可能是可取的。
isnot_distinct_from
(other)¶实施 IS NOT DISTINCT FROM
操作符。
在大多数平台上呈现“a与b不同”;在某些平台上,例如sqlite可能呈现“a是b”。
1.1 新版功能.
like
(other, escape=None)¶继承 like()
方法 ColumnOperators
实施 like
操作符。
在列上下文中,生成表达式::
a LIKE other
例如。::
stmt = select([sometable]).\
where(sometable.c.column.like("%foobar%"))
local_attr
¶“本地” MapperProperty
引用人: AssociationProxyInstance
.
match
(other, **kwargs)¶继承 match()
方法 ColumnOperators
实现特定于数据库的“match”运算符。
match()
尝试解析为后端提供的类似匹配的函数或运算符。示例包括:
PostgreSQL-呈现 x @@ to_tsquery(y)
MySQL -渲染器 MATCH (x) AGAINST (y IN BOOLEAN MODE)
Oracle-呈现 CONTAINS(x, y)
其他后端可能提供特殊的实现。
没有任何特殊实现的后端将发出“match”操作符。例如,这与sqlite兼容。
notilike
(other, escape=None)¶继承 notilike()
方法 ColumnOperators
实施 NOT ILIKE
操作符。
这相当于使用否定 ColumnOperators.ilike()
,即 ~x.ilike(y)
.
notin_
(other)¶继承 notin_()
方法 ColumnOperators
实施 NOT IN
操作符。
这相当于使用否定 ColumnOperators.in_()
,即 ~x.in_(y)
.
在这种情况下 other
是一个空序列,编译器生成一个“empty not in”表达式。这将默认表达式“1=1”在所有情况下都生成“真”。这个 create_engine.empty_in_strategy
可用于更改此行为。
在 1.2 版更改: 这个 ColumnOperators.in_()
和 ColumnOperators.notin_()
现在,默认情况下,运算符为空序列生成一个“静态”表达式。
notlike
(other, escape=None)¶继承 notlike()
方法 ColumnOperators
实施 NOT LIKE
操作符。
这相当于使用否定 ColumnOperators.like()
,即 ~x.like(y)
.
nullsfirst
()¶继承 nullsfirst()
方法 ColumnOperators
产生一个 nullsfirst()
针对父对象的子句。
nullslast
()¶继承 nullslast()
方法 ColumnOperators
产生一个 nullslast()
针对父对象的子句。
op
(opstring, precedence=0, is_comparison=False, return_type=None)¶生成通用运算符函数。
例如。::
somecolumn.op("*")(5)
生产::
somecolumn * 5
此函数还可用于显式地生成位运算符。例如::
somecolumn.op('&')(0xff)
是中的值的位与 somecolumn
.
operator¶ -- 将作为该元素和传递给生成函数的表达式之间的中缀运算符输出的字符串。
precedence¶ -- 在对表达式加括号时应用于运算符的优先级。当对具有更高优先级的另一个运算符应用时,较低的数字将导致表达式加括号。默认值为 0
低于除逗号之外的所有运算符 (,
) AS
运算符。值100将大于或等于所有运算符,-100将小于或等于所有运算符。
is_comparison¶ -- 如果为真,则该运算符将被视为“比较”运算符,即计算为布尔真/假值,如 ==
, >
等等。应设置此标志,以便ORM关系可以确定在自定义联接条件中使用的运算符是比较运算符。…versionAdded::0.9.2-添加了 Operators.op.is_comparison
标志。
return_type¶ -- 一 TypeEngine
类或对象,它将强制此运算符生成的表达式的返回类型为该类型。默认情况下,指定 Operators.op.is_comparison
将决心 Boolean
,而那些不属于左侧操作数的类型。…versionAdded::1.2.0b3-添加了 Operators.op.return_type
争论。
operate
(op, *other, **kwargs)¶对参数进行运算。
这是最低级别的操作,提升 NotImplementedError
默认情况下。
在子类上覆盖此项可以允许将公共行为应用于所有操作。例如,重写 ColumnOperators
申请 func.lower()
左右两侧:
class MyComparator(ColumnOperators):
def operate(self, op, other):
return op(func.lower(self), func.lower(other))
remote_attr
¶“遥控器” MapperProperty
引用人: AssociationProxyInstance
.
…
:attr:`.AssociationProxyInstance.attr`
:attr:`.AssociationProxyInstance.local_attr`
reverse_operate
(op, other, **kwargs)¶继承 reverse_operate()
方法 Operators
对参数进行反向运算。
用法与 operate()
.
scalar
¶返回 True
如果这样 AssociationProxyInstance
在本地端代理一个标量关系。
startswith
(other, **kwargs)¶继承 startswith()
方法 ColumnOperators
实施 startswith
操作符。
生成一个类似表达式,该表达式根据字符串值开头的匹配项进行测试:
column LIKE <other> || '%'
例如。::
stmt = select([sometable]).\
where(sometable.c.column.startswith("foobar"))
因为操作符使用 LIKE
,通配符 "%"
和 "_"
存在于<other>表达式中的也将表现为通配符。对于文本字符串值, ColumnOperators.startswith.autoescape
标志可以设置为 True
将转义应用于字符串值中出现的这些字符,以便它们与自身匹配,而不是作为通配符匹配。或者, ColumnOperators.startswith.escape
参数将建立一个给定字符作为转义字符,当目标表达式不是文本字符串时可以使用该字符。
other¶ -- 要比较的表达式。这通常是一个纯字符串值,但也可以是任意的SQL表达式。类似通配符 %
和 _
默认情况下不转义,除非 ColumnOperators.startswith.autoescape
标志设置为真。
autoescape¶ -- 布尔值;如果为true,则在like表达式中建立转义符,然后将其应用于 "%"
, "_"
以及转义符本身在比较值中,该值被假定为文本字符串而不是SQL表达式。表达式如::somecolumn.startswith(“foo%bar”,autoescape=true)将呈现为::somecolumn-like :param || '%' ESCAPE '/' With the value of :param as "foo/%bar"
. .. versionadded:: 1.2 .. versionchanged:: 1.2.0 The ColumnOperators.startswith.autoescape
参数现在是一个简单的布尔值而不是一个字符;转义字符本身也被转义,并默认为正斜杠,可以使用 ColumnOperators.startswith.escape
参数。
escape¶ -- 一个字符,当给定时将用 ESCAPE
关键字将该字符建立为转义字符。然后可以将此字符置于 %
和 _
允许它们充当自己而不是通配符。表达式如::somecolumn.startswith(“foo/%bar”,escape=“^”)将呈现为::somecolumn-like :param || '%' ESCAPE '^' The parameter may also be combined with ColumnOperators.startswith.autoescape
::somecolumn.startswith(“foo%bar^bat”,escape=“^”,autoescape=true),其中,给定的文本参数将转换为 "foo^%bar^^bat"
在被传递到数据库之前。
sqlalchemy.ext.associationproxy.
ASSOCIATION_PROXY
= symbol('ASSOCIATION_PROXY')¶InspectionAttr
那是类型的 AssociationProxy
.
分配给 InspectionAttr.extension_type
属性。