Feature Request : Support for SOFT_DELETE
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).
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.
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:
- What will happen if I alter the value of
config.ETAG,config.LAST_UPDATEDorconfig.DATE_CREATEDinsettings? - Why are there duplicated default values in
eve/__init__.pyandeve/default_settings.pywhile the number of fields are not identical? How about import these values fromeve/default_settings.pydirectly? So we haveDELETEDinevemodule.
Do you have some suggestions?
@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.
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 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.