eve-sqlalchemy icon indicating copy to clipboard operation
eve-sqlalchemy copied to clipboard

Feature Request : Support for SOFT_DELETE

Open mandarvaze opened this issue 9 years ago • 5 comments

When I enable SOFT_DELETE in the settings.py, I get _deleted is an invalid argument error.

I can't add _deleted field myself either, because then I get the following error:

eve.exceptions.SchemaException: field(s) "_deleted" not allowed in "xyz" schema (they will be handled automatically).

mandarvaze avatar Apr 27 '16 18:04 mandarvaze

I just discovered that we miss two test cases in tests/delete.py: TestSoftDelete and TestResourceSpecificSoftDelete. So the first step to tackle this issue would be to add those (and inherit Eve's test cases) and see what needs fixing.

dkellner avatar Feb 17 '17 11:02 dkellner

I also require this feature. I tried to add config.DELETED to this tuple, but it failed with the issue that the eve module has no DELETED attribute.

I've seen the source of eve.utils.config, which tries to read config from current_app.config then fallbacks to eve. However, the decorator registerSchema is always executed out of the context of eve app(or flask app) and always read config from the eve module.

So I have multiple questions:

  1. What will happen if I alter the value of config.ETAG, config.LAST_UPDATED or config.DATE_CREATED in settings?
  2. Why are there duplicated default values in eve/__init__.py and eve/default_settings.py while the number of fields are not identical? How about import these values from eve/default_settings.py directly? So we have DELETED in eve module.

Do you have some suggestions?

huiyiqun avatar Apr 03 '17 03:04 huiyiqun

@huiyiqun While I cannot really answer your second question (it would be better to ask that at pyeve/eve directly), I am currently working on a fix for your first. At the moment we have several problems due to the use of registerSchema as a decorator, which is usually evaluated before the actual app creation. The plan to tackle all of them at once is to stop using a decorator, but have a convenient way to convert your SQLAlchemy models to Eve resource definitions in your settings.py. And explicitly provide some values that are needed in that process, e.g. the name of the ETAG field.

dkellner avatar Apr 07 '17 07:04 dkellner

For anyone that might find this useful: I managed a janky SOFT_DELETE implementation by turning on the SOFT_DELETE configuration, adding the _deleted column to my models, and then adding a on_pre_GET hook on the application. Under the hood, the HTTP DELETE function is handled by Eve/Eve-SQLAlchemy, as expected. Note that there there is an inconsistency where retrieving embedded resources do not filter out the _deleted resources.

EDIT: Some code

# Register filter hook
def register_filters(app):
    app.on_pre_GET += pre_GET_callback


def pre_GET_callback(resource, request, lookup):
    if '_deleted' in request.args.get('where', {}):
        lookup['_deleted'] = True
    else:
        lookup['_deleted'] = False

# Models
class CommonColumns(Base):
    __abstract__ = True
    _created = Column(DateTime, default=func.now())
    _updated = Column(DateTime, default=func.now(), onupdate=func.now())
    _deleted = Column(Boolean,
                      server_default=expression.false(),
                      nullable=False)
    _etag = Column(String(40))

ktal90 avatar Dec 17 '18 00:12 ktal90

@ktal90 Would you be interested in working on a proper implementation? As mentioned above, the first step would be to enable those missing tests from Eve.

dkellner avatar Dec 17 '18 08:12 dkellner