Skip to content

Creating model instance does not respect "viewonly" relationship attribute #188

@ktal90

Description

@ktal90

I have a semi-complex relationship using a secondary. This relationship is useful to me because when querying, but I do not want to write to it. SQLAlchemy has the viewonly option that I can set on the relationship to bypass setting that relationship when I insert a new record. Eve-SQLAlchemy, however, has issues when building the model instance for a resource that has this relationship associated with it. Eve-SQLAlchemy finds this relationship as a list, which is fine, and during insert time, building the model instance fails. This is unfortunate because evaluating this field when inserting is not necessary, since I've already set this as a "viewonly" field. Following is an example of my model. The relationship in question is "organization":

class CommonColumns(Base):
    __abstract__ = True
    _created = Column(DateTime, default=func.now())
    _updated = Column(DateTime, default=func.now(), onupdate=func.now())
    _etag = Column(String(40))

    @declared_attr
    def created_by_id(cls):
        return Column(Integer,
                      ForeignKey('users.id'),
                      default=get_current_user_id)

    @declared_attr
    def updated_by_id(cls):
        return Column(Integer,
                      ForeignKey('users.id'),
                      default=get_current_user_id,
                      onupdate=get_current_user_id)

    @declared_attr
    def created_by(cls):
        return relationship(
            'Users',
            foreign_keys='{}.created_by_id'.format(cls.__name__))

    @declared_attr
    def updated_by(cls):
        return relationship(
            'Users',
            foreign_keys='{}.updated_by_id'.format(cls.__name__))

    @declared_attr
    def organization(cls):
        return relationship(
            'Organizations',
            primaryjoin='{}.created_by_id==Users.id'.format(cls.__name__),
            secondary='join(Users, Organizations, Users.organization_id == Organizations.id)',  # noqa
            viewonly=True)

class Users(Base):
    __tablename__ = 'users'
    _created = Column(DateTime, default=func.now())
    _updated = Column(DateTime, default=func.now(), onupdate=func.now())
    id = Column(Integer, primary_key=True, autoincrement=True)
    organization_id = Column(Integer,
                             ForeignKey('organizations.id'),
                             nullable=False)
    organization = relationship('Organizations',
                                back_populates='users')

class Organizations(Base):
    __tablename__ = 'organizations'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(128))
    users = relationship('Users', back_populates='organization')

Is there a better way to set up this relationship and/or how can we properly handle building up the model instead of it failing to do so?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions