gpt4 book ai didi

python - 在 SQLAlchemy 中更新关联对象中的字段

转载 作者:行者123 更新时间:2023-11-30 23:32:16 28 4
gpt4 key购买 nike

我在 SQLAlchemy 中有一个关联对象,它包含其他 2 个对象的一些额外信息(实际上是单个字段)。

第一个对象是 Photo 模型,第二个对象是 PhotoSet,关联对象称为 PhotoInSet,它保存 >position 属性告诉我们当前 PhotoSetPhoto 的位置。

class Photo(Base):

__tablename__ = 'photos'
id = Column(Integer, primary_key=True)
filename = Column(String(128), index=True)
title = Column(String(256))
description = Column(Text)
pub_date = Column(SADateTime)

class PhotoInSet(Base):

__tablename__ = 'set_order'
photo_id = Column(Integer, ForeignKey('photos.id'), primary_key=True)
photoset_id = Column(Integer, ForeignKey('photo_set.id'), primary_key=True)
position = Column(Integer)
photo = relationship('Photo', backref='sets')

def __repr__(self):
return '<PhotoInSet %r>' % self.position


class PhotoSet(Base):

__tablename__ = 'photo_set'
id = Column(Integer, primary_key=True)
name = Column(String(256))
description = Column(Text)
timestamp = Column(SADateTime)
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship('User', backref=backref('sets', lazy='dynamic'))
photo_id = Column(Integer, ForeignKey('photos.id'))
photos = relationship('PhotoInSet', backref=backref('set', lazy='select'))

我可以毫无问题地创建一个新的PhotoSet来保存位置并创建关系,(大致)是这样完成的:

    # Create the Set
new_set = PhotoSet(name, user)

# Add the photos with positions applied in the order they came
new_set.photos.extend(
[
PhotoInSet(position=pos, photo=photo)
for pos, photo in
enumerate(photo_selection)
]
)

但是我在尝试弄清楚如何在订单更改时更新位置时遇到了很多麻烦。

如果我有 3 个 Photo 对象,其 id 分别为 1、2 和 3,位置分别为 1、2 和 3,创建后将如下所示:

>>> _set = PhotoSet.get(1)
>>> _set.photos
[<PhotoInSet 1>, <PhotoInSet 2>, <PhotoInSet 3>]

如果顺序发生变化(让我们反转本例的顺序),SQLAlchemy 是否可以帮助我更新 position 值?到目前为止,我对我能想到的任何方法都不满意。

最简洁的方法是什么?

最佳答案

看看Ordering List扩展名:

orderinglist is a helper for mutable ordered relationships. It will intercept list operations performed on a relationship()-managed collection and automatically synchronize changes in list position onto a target scalar attribute.

我相信您可以将架构更改为:

from sqlalchemy.ext.orderinglist import ordering_list

# Photo and PhotoInSet stay the same...

class PhotoSet(Base):
__tablename__ = 'photo_set'
id = Column(Integer, primary_key=True)
name = Column(String(256))
description = Column(Text)
photo_id = Column(Integer, ForeignKey('photos.id'))
photos = relationship('PhotoInSet',
order_by="PhotoInSet.position",
collection_class=ordering_list('position'),
backref=backref('set', lazy='select'))

# Sample usage...
session = Session()

# Create two photos, add them to the set...
p_set = PhotoSet(name=u'TestSet')

p = Photo(title=u'Test')
p2 = Photo(title='uTest2')

p_set.photos.append(PhotoInSet(photo=p))
p_set.photos.append(PhotoInSet(photo=p2))
session.add(p_set)

session.commit()
print 'Original list of titles...'
print [x.photo.title for x in p_set.photos]
print ''

# Change the order...
p_set.photos.reverse()
# Any time you change the order of the list in a way that the existing
# items are in a different place, you need to call "reorder". It will not
# automatically try change the position value for you unless you are appending
# an object with a null position value.
p_set.photos.reorder()
session.commit()

p_set = session.query(PhotoSet).first()
print 'List after reordering...'
print [x.photo.title for x in p_set.photos]

该脚本的结果...

Original list of titles...
[u'Test', u'uTest2']

List after reordering...
[u'uTest2', u'Test']

在您的评论中,您说...

So this would mean that if I assign a new list to _set.photos I get the positioning for free?

我怀疑情况确实如此。

关于python - 在 SQLAlchemy 中更新关联对象中的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19470676/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com