python – 在sqlalchemy映射集合中使用值元组
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 在sqlalchemy映射集合中使用值元组,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含6275字,纯文字阅读大概需要9分钟。
内容图文
![python – 在sqlalchemy映射集合中使用值元组](/upload/InfoBanner/zyjiaocheng/898/d8754684768741d99651a31e018419b2.jpg)
在多对多关系中,我在关联表上有一些额外的数据来描述关系(数量和布尔值).我想使用映射集合来避免直接使用关联对象,但我无法弄清楚如何使用元组来映射映射中的值.据我所知,Attribute as dict of lists using middleman table with SQLAlchemy是相似的,但倒退.
为了说明这一点,我想做这样的事情:
>>> collection.items[item] = (3, True)
>>> collection.items[item] = (1, False)
>>> colletion.items
{"item name": (3, True), "item name": (1, False)}
这……工作……但最终SQLAlchemy尝试将元组放入数据库(我将尝试重新创建它).
我也尝试在键中使用元组(相关对象和其他列之一),但它看起来很糟糕,但它不起作用:
>>> collection.items[item, True] = 3
>>> collection.items[item, False] = 1
>>> collection.items
{(<item>, True): 3, (<item>, False): 1}
我可以将项目名称和一个值放在映射的集合中而不会出现问题:我有另一个(结构相同)形式的这种关系,我通过建立两个关系(和关联代理)来解决它们根据布尔值划分它们之间的关联表value,它们的创建函数正确设置布尔值,没有任何进一步的干扰.不幸的是,在这种情况下,布尔值指定了一个小的语义差异(应用程序代码需要将项目视为一个组),而在当前的问题中,这是一个不可忽视的外观差异(应用程序代码不应该将项目视为组,而是值确实会改变项目的显示方式,因此也是如此.
解决方法:
链接的答案包含所有组件. attribute_mapped_collection和association_proxy可以一起做很多事情.首先是string-> tuple(int,boolean)的字典(为m2m更新):
from sqlalchemy import Integer, Boolean, String, Column, create_engine, \
ForeignKey
from sqlalchemy.orm import Session, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
Base = declarative_base()
class SomeClass(Base):
__tablename__ = 'sometable'
id = Column(Integer, primary_key=True)
tuple_elements = relationship(
"TupleAssociation",
collection_class=attribute_mapped_collection("name"),
cascade="all, delete-orphan"
)
items = association_proxy("tuple_elements", "as_tuple")
class TupleAssociation(Base):
__tablename__ = 'tuple_association'
parent_id = Column(Integer, ForeignKey('sometable.id'), primary_key=True)
tuple_id = Column(Integer, ForeignKey("tuple_data.id"), primary_key=True)
name = Column(String)
tuple_element = relationship("TupleElement")
def __init__(self, key, tup):
self.name = key
self.tuple_element = TupleElement(tup)
@property
def as_tuple(self):
return self.tuple_element.as_tuple
class TupleElement(Base):
__tablename__ = 'tuple_data'
id = Column(Integer, primary_key=True)
col1 = Column(Integer)
col2 = Column(Boolean)
def __init__(self, tup):
self.col1, self.col2 = tup
@property
def as_tuple(self):
return self.col1, self.col2
e = create_engine('sqlite://')
Base.metadata.create_all(e)
s = Session(e)
collection = SomeClass()
collection.items["item name 1"] = (3, True)
collection.items["item name 2"] = (1, False)
print collection.items
s.add(collection)
s.commit()
collection = s.query(SomeClass).first()
print collection.items
这里是关联上的元组和端点上的名称的另一种方式:
from sqlalchemy import Integer, Boolean, String, Column, create_engine, \
ForeignKey
from sqlalchemy.orm import Session, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
Base = declarative_base()
class SomeClass(Base):
__tablename__ = 'sometable'
id = Column(Integer, primary_key=True)
tuple_elements = relationship(
"TupleAssociation",
collection_class=attribute_mapped_collection("name"),
cascade="all, delete-orphan"
)
items = association_proxy("tuple_elements", "as_tuple")
class TupleAssociation(Base):
__tablename__ = 'tuple_association'
parent_id = Column(Integer, ForeignKey('sometable.id'), primary_key=True)
name_id = Column(Integer, ForeignKey("name_data.id"), primary_key=True)
col1 = Column(Integer)
col2 = Column(Boolean)
name_element = relationship("NameElement")
def __init__(self, key, tup):
self.name_element = NameElement(name=key)
self.col1, self.col2 = tup
@property
def name(self):
return self.name_element.name
@property
def as_tuple(self):
return self.col1, self.col2
class NameElement(Base):
__tablename__ = 'name_data'
id = Column(Integer, primary_key=True)
name = Column(String)
e = create_engine('sqlite://', echo=True)
Base.metadata.create_all(e)
s = Session(e)
collection = SomeClass()
collection.items["item name 1"] = (3, True)
collection.items["item name 2"] = (1, False)
print collection.items
s.add(collection)
s.commit()
collection = s.query(SomeClass).first()
print collection.items
这可能就是你所需要的.如果您正在使用支持SQL元组的Postgresql,您可以使用hybrids plus tuple_()向上面添加更多内容,以便as_tuple也可以在SQL级别使用(下面也使用一对多而不是关联对象)仅举例):
from sqlalchemy import Integer, Boolean, String, Column, create_engine, \
ForeignKey
from sqlalchemy.orm import Session, relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.ext import hybrid
from sqlalchemy.sql import tuple_
Base = declarative_base()
class SomeClass(Base):
__tablename__ = 'sometable'
id = Column(Integer, primary_key=True)
tuple_elements = relationship(
"TupleElement",
collection_class=attribute_mapped_collection("name"),
cascade="all, delete-orphan"
)
items = association_proxy("tuple_elements", "as_tuple")
class TupleElement(Base):
__tablename__ = 'tuple_data'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('sometable.id'), nullable=False)
name = Column(String)
col1 = Column(Integer)
col2 = Column(Boolean)
def __init__(self, key, tup):
self.name = key
self.col1, self.col2 = tup
@hybrid.hybrid_property
def as_tuple(self):
return self.col1, self.col2
@as_tuple.expression
def as_tuple(self):
return tuple_(self.col1, self.col2)
e = create_engine('postgresql://scott:tiger@localhost/test', echo=True)
Base.metadata.drop_all(e)
Base.metadata.create_all(e)
s = Session(e)
collection = SomeClass()
collection.items["item name 1"] = (3, True)
collection.items["item name 2"] = (1, False)
print collection.items
s.add(collection)
s.commit()
q = s.query(SomeClass).join(SomeClass.tuple_elements)
assert q.filter(TupleElement.as_tuple == (3, True)).first() is collection
assert q.filter(TupleElement.as_tuple == (5, False)).first() is None
print s.query(TupleElement.as_tuple).all()
内容总结
以上是互联网集市为您收集整理的python – 在sqlalchemy映射集合中使用值元组全部内容,希望文章能够帮你解决python – 在sqlalchemy映射集合中使用值元组所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。