我有一个我需要解决的问题.核心问题是我想在JPA中为JoinTable for ManyToMany关系添加额外的列.就我而言,我有以下实体.
主题是一个简单的实体,它有许多RemoteDocument(一个RemoteDocument可能被许多主题引用,因此它应该是ManyToMany关系).此外,RemoteDocument实体是只读的,因为它可能只能从Oracle物化视图中读取,而且禁止更改此物化视图.所以我想存储与某些主题相关的RemoteDocuments的顺序.事实上,我可以使用其他实体做类似的事情:
@Entity
public class Topic {
@Id
private Long id;
@Basic
private String name;
@OneToMany
private Set<TopicToRemoteDocument> association;
}
@Entity
public class RemoteDocument {
@Id
private Long id;
@Basic
private String description;
}
@Entity
public class TopicToRemoteDocument {
@OneToOne
private Topic topic;
@OneToOne
private RemoteDocument remoteDocument;
@Basic
private Integer order;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,附加实体TopicToRemoteDocument帮助我用OneToMany替换ManyToMany关联并添加额外的字段顺序.
但我想拥有ManyToMany关系,但在连接表中配置了额外的列
我有一个相互关联的Django模型的迷茫迷宫,其中包含描述关系的多对多字段.
从QuerySet获取相关模型的唯一成员列表的最简洁方法是什么?
如果我有一个Item模型,其中ManyToMany组指向Groups模型.
如果我有一个项目的查询集,'items',我该如何得到这个:
groups = items[0].groups.all().values_list('name', flat=True)
Run Code Online (Sandbox Code Playgroud)
但对于整套?我是否需要遍历它们并执行set().intersect()?
我已经阅读了关于构建多对多关系的SQLAlchemy文档和教程,但是当关联表包含多于2个外键时,我无法弄清楚如何正确地完成它.
我有一个项目表,每个项目都有很多细节.许多项目的细节可以相同,因此项目和细节之间存在多对多关系
我有以下内容:
class Item(Base):
__tablename__ = 'Item'
id = Column(Integer, primary_key=True)
name = Column(String(255))
description = Column(Text)
class Detail(Base):
__tablename__ = 'Detail'
id = Column(Integer, primary_key=True)
name = Column(String)
value = Column(String)
Run Code Online (Sandbox Code Playgroud)
我的关联表是(它在代码中的其他2之前定义):
class ItemDetail(Base):
__tablename__ = 'ItemDetail'
id = Column(Integer, primary_key=True)
itemId = Column(Integer, ForeignKey('Item.id'))
detailId = Column(Integer, ForeignKey('Detail.id'))
endDate = Column(Date)
Run Code Online (Sandbox Code Playgroud)
在文档中,据说我需要使用"关联对象".我无法弄清楚如何正确使用它,因为它与mapper表单混合声明,并且示例似乎不完整.我添加了这一行:
details = relation(ItemDetail)
Run Code Online (Sandbox Code Playgroud)
作为Item类和行的成员:
itemDetail = relation('Detail')
Run Code Online (Sandbox Code Playgroud)
作为关联表的成员,如文档中所述.
当我执行item = session.query(Item).first()时,item.details不是Detail对象的列表,而是ItemDetail对象的列表.
如何在Item对象中正确获取详细信息,即item.details应该是Detail对象的列表?
这可能是侮辱性的简单而且值得Nelson Muntz笑,但我有一个真正的脑死亡时刻试图在不同的模型关系中建立多对多的联系.
我有以下型号(简化为您的享受!):
class Document(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(User, blank=True)
content = models.TextField(blank=True)
private = models.BooleanField(default=False)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
friends = models.ManyToManyField(User, symmetrical=False,
related_name='user_friends')
ignored = models.ManyToManyField(User, symmetrical=False,
related_name='user_ignored')
Run Code Online (Sandbox Code Playgroud)
成像以下用户:
搜索文档的用户应该生成以下内容:
基本上,我正在精神上努力找出过滤器以返回我上面描述的查询集.有人有任何想法吗?
编辑
感谢Ferdinands的回答,我能够通过他给我的开始坚持到我想要的东西.首先,我们希望得到一个与我结识的人员名单,这是通过多对多关系进行反向查询:
friendly_authors = self.user.user_friends.all()
Run Code Online (Sandbox Code Playgroud)
得到我忽略的所有人:
my_ignored = UserProfile.objects.get(user=self.user).ignored.all()
Run Code Online (Sandbox Code Playgroud)
获取我可以查看的文档列表 - 可以查看,使用或编写文档的文档,这些文档可能是我的朋友,但我没有忽略过:
docs = Document.objects.filter(
(Q(viewable=True) | Q(author=self.user) | Q(author__in=friendly_authors))
& ~Q(author__in=my_ignored)
)
Run Code Online (Sandbox Code Playgroud) 我试图在sqlalchemy中创建一个自引用的多对多关系(这意味着Line可以有许多父行和许多子行),如下所示:
Base = declarative_base()
class Association(Base):
__tablename__ = 'association'
prev_id = Column(Integer, ForeignKey('line.id'), primary_key=True)
next_id = Column(Integer, ForeignKey('line.id'), primary_key=True)
class Line(Base):
__tablename__ = 'line'
id = Column(Integer, primary_key = True)
text = Column(Text)
condition = Column(Text)
action = Column(Text)
next_lines = relationship(Association, backref="prev_lines")
class Root(Base):
__tablename__ = 'root'
name = Column(String, primary_key = True)
start_line_id = Column(Integer, ForeignKey('line.id'))
start_line = relationship('Line')
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:sqlalchemy.exc.ArgumentError:无法确定关系Line.next_lines上的父/子表之间的连接条件.指定'primaryjoin'表达式.如果存在'secondary',则还需要'secondaryjoin'.
你知道我怎么能解决这个问题吗?
问题:
我在两个实体A和B 之间有多对多的关联.我将一个实体设置为他们关系的所有者(inverse = true在b.hbm.xml中的A集合中).
当我删除A实体时,删除连接表中的相应记录.
当我删除B实体时,不删除连接表中的相应记录(完整性违规例外).
-
让我们考虑一些非常简单的例子:
class A{
Set<B> bset=new HashSet<B>();
//...
}
class B{
Set<A> aset=new HashSet<A>();
//...
}
Run Code Online (Sandbox Code Playgroud)
文件a.hbm.xml [m-to-m mappings only]:
<set name="bset" table="AB">
<key name="a_id"/>
<many-to-many column="b_id" class="B"/>
</set>
Run Code Online (Sandbox Code Playgroud)
文件b.hbm.xml [m-to-m mappings only]:
<set name="aset" table="AB" inverse="true">
<key name="b_id"/>
<many-to-many column="a_id" class="A"/>
</set> …
Run Code Online (Sandbox Code Playgroud) 我有像这样的多对多关系的模型:
class Contact(models.Model):
name = models.TextField()
address = models.TextField()
class Mail(models.Model):
to = models.ManyToManyField(Contact, related_name='received_mails')
cc = models.ManyToManyField(Contact, related_name='cced_mails')
Run Code Online (Sandbox Code Playgroud)
我想获取给定电子邮件的to字段或cc字段中的联系人集.我们试试吧:
>>> Contact.objects.filter(received_mails__id=111)
[<Contact: fred@foo.com>]
>>> Contact.objects.filter(cced_mails__id=111)
[<Contact: joe@bar.com>]
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.我们为每个关系都有一个联系人.但是将它们放入同一个QuerySet会很好.
>>> Contact.objects.filter(Q(received_mails__id=111) | Q(cced_mails__id=111))
[<Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, <Contact: joe@bar.com>, '...(remaining elements truncated)...']
Run Code Online (Sandbox Code Playgroud)
发生了什么?我觉得这与在SQL中连接表有关,但我真的不明白在很多关系下发生了什么.可能是我想要做的事情是愚蠢的,或者有一种简单的方法可以做到这一点.无论哪种方式,我很高兴能够走上正确的道路.
编辑:这是QuerySet的查询:
SELECT `mailshareapp_contact`.`id`, …
Run Code Online (Sandbox Code Playgroud) 我在奏鸣曲管理编辑表单中实现多对多关系时遇到问题,具有以下结构.
purchase (id, total_price, discount, created_at)
purchase_product (purchase_id, product_id, quantity)
product (id, title, desc, price, thumbnail, created_at)
Run Code Online (Sandbox Code Playgroud)
我见过很多线程,并尝试过其中列出的解决方案.我试过了
->add('products', 'sonata_type_model', array('by_reference' => false))
Run Code Online (Sandbox Code Playgroud)
我收到以下错误
No entity manager defined for class Doctrine\ORM\PersistentCollection
Run Code Online (Sandbox Code Playgroud)
然后,当我找不到解决这个问题的方法时,我切换到了
->add('products', 'sonata_type_collection', array(), array('edit' => 'inline', 'inline' => 'table')
Run Code Online (Sandbox Code Playgroud)
我收到以下错误
INVALID MODE type : sonata_type_collection - mapping : 8
Run Code Online (Sandbox Code Playgroud)
我也无法弄清楚如何从purchase_product表中获取和显示数量.
任何指针和帮助都非常感谢.
情况:
所以,我在SQLAlchemy中使用关联表有一个基本的多对多关系.
例如,一个人可以参加很多聚会,一个聚会可以有很多人作为嘉宾:
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = db.Column(db.String(50))
class SexyParty(Base):
__tablename__ = 'sexy_party'
id = Column(Integer, primary_key=True)
guests = relationship('Person', secondary='guest_association',
lazy='dynamic', backref='parties')
guest_association = Table(
'guest_association',
Column('user_id', Integer(), ForeignKey('person.id')),
Column('sexyparty.id', Integer(), ForeignKey('sexyparty.id'))
)
Run Code Online (Sandbox Code Playgroud)
通常,如果我想在聚会上添加一个客人列表,我会做这样的事情:
my_guests = [prince, olivia, brittany, me]
my_party.guests = guests
db.session.commit()
Run Code Online (Sandbox Code Playgroud)
......王子,奥利维亚<Person>
和布列塔尼都是实例,my_party就是一个<SexyParty>
例子.
我的问题:
我想使用人员ID而不是实例将访客添加到聚会中.例如:
guest_ids = [1, 2, 3, 5]
my_party.guests = guest_ids # <-- This fails, because guest_ids
# are not …
Run Code Online (Sandbox Code Playgroud) 我想知道在将表拆分成多对多关系时如何最好地迁移我的数据.我已经做了一个简化的例子,我还会发布一些我想出的解决方案.我正在使用Postgresql数据库.
迁移之前
表人
ID Name Pet PetName
1 Follett Cat Garfield
2 Rowling Hamster Furry
3 Martin Cat Tom
4 Cage Cat Tom
Run Code Online (Sandbox Code Playgroud)
迁移后
表人
ID Name
1 Follett
2 Rowling
3 Martin
4 Cage
Run Code Online (Sandbox Code Playgroud)
表宠物
ID Pet PetName
6 Cat Garfield
7 Hamster Furry
8 Cat Tom
9 Cat Tom
Run Code Online (Sandbox Code Playgroud)
表PersonPet
FK_Person FK_Pet
1 6
2 7
3 8
4 9
Run Code Online (Sandbox Code Playgroud)
笔记:
我的解决方案
ALTER …
Run Code Online (Sandbox Code Playgroud) many-to-many ×10
python ×4
django ×3
sql ×3
sqlalchemy ×3
relationship ×2
associations ×1
hibernate ×1
java ×1
jpa ×1
lookup ×1
postgresql ×1
sonata-admin ×1
symfony ×1