添加关系后,instrumentedlist导致sqlalchemy

时间:2015-08-20 12:39:59

标签: python sqlalchemy relationship

我已经定义了sqlalchemy模型:

class Item(base.Base):
    __tablename__ = 'list_item'

    id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)
    body = sqlalchemy.Column(sqlalchemy.Unicode)

    list_id = sqlalchemy.Column(
        sqlalchemy.Integer, sqlalchemy.ForeignKey('list.id'), nullable=False)

    # container holding images grouped by type
    image_container = sqlalchemy.orm.relationship(
        'ImageContainer', backref="item", cascade="all, delete-orphan")


class List(base.Base):
    __tablename__ = 'list'

    id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)

    title = sqlalchemy.Column(
        sqlalchemy.Unicode(255), nullable=False, unique=True)

    # relationships
    items = sqlalchemy.orm.relationship(
        'Item', cascade="all, delete-orphan", backref='list')


class BaseImageContainer(object):
    container_type = sqlalchemy.Column(sqlalchemy.Unicode(128))

    @sqlalchemy.ext.declarative.declared_attr
    def image(cls):  # pylint: disable=no-self-argument
        return sqlalchemy.orm.relationship(
            'Image', uselist=False, backref='items')

    @sqlalchemy.ext.declarative.declared_attr
    def image_id(cls):  # pylint: disable=no-self-argument
        return sqlalchemy.Column(
            sqlalchemy.Integer, sqlalchemy.ForeignKey('image.id'),
            primary_key=True)

    sqlalchemy.UniqueConstraint(
        'obj_id', 'container_type', name='one_image_per_container_type')


class ImageContainer(base.Base, BaseImageContainer):
    __tablename__ = 'image_container_item'

    obj_id = sqlalchemy.Column(
        sqlalchemy.Integer, sqlalchemy.ForeignKey('list_item.id'),
        primary_key=True)


class Image(base.Base):
    '''Represents an Image at a high level (title, credits, description)'''
    __tablename__ = 'image'

    id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True)

    title = sqlalchemy.Column(sqlalchemy.Unicode)
    description = sqlalchemy.Column(sqlalchemy.Unicode)

我正在使用以下代码将图像添加到容器中:

for container_name, image in images:
   container = ImageContainer()
   container.container_type = container_name
   container.image = image

   item.image_container.append(container)

在最后一行追加导致查询调用的autoflush(因为我们处于构建列表和项目对象的中间,因为list_id不能为null,所以它最终会导致致命错误。)

但如果最后一行被替换为:

   container.item = item

它全是绿色。

我对List和Item有完全相同的问题。

List.items.append(Item)

导致Query-invoked autoflush,但

Item.list = List

再次好起来。

这是否意味着在构建复杂模型时我们不应该在InstrumentedList上使用append?

0 个答案:

没有答案