Repository: deepset-ai/haystack

Issue:
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1093, "You can't specify target table 'document' for update in FROM clause")
**Describe the bug**
A clear and concise description of what the bug is.
when I use delete_documents method,I get the error, and my demo is:
```
milvus2_document_store = Milvus2DocumentStore(sql_url="mysql+pymysql://xxxx", host="xxxx", index="milvus_data_mysql")
milvus2_document_store.use_windowed_query=False
milvus2_document_store.delete_documents(index="milvus_data_mysql", ids=["d7cc36dad9ab0403fb9489ec55720d23"])
```

**Error message**
Error that was thrown (if available)
```
Traceback (most recent call last):
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1900, in _execute_context
    self.dialect.do_execute(
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 736, in do_execute
    cursor.execute(statement, parameters)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/cursors.py", line 148, in execute
    result = self._query(query)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/cursors.py", line 310, in _query
    conn.query(q)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/connections.py", line 548, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/connections.py", line 775, in _read_query_result
    result.read()
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/connections.py", line 1156, in read
    first_packet = self.connection._read_packet()
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/connections.py", line 725, in _read_packet
    packet.raise_for_error()
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.OperationalError: (1093, "You can't specify target table 'document' for update in FROM clause")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/youbo/PycharmProjects/DocQA/data_preprocess_new.py", line 807, in <module>
    milvus2_document_store.delete_documents(index="milvus_data_mysql", ids=["d7cc36dad9ab0403fb9489ec55720d23"])
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/haystack/document_stores/milvus2.py", line 489, in delete_documents
    super().delete_documents(index=index, filters=filters, ids=ids)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/haystack/document_stores/sql.py", line 670, in delete_documents
    self.session.query(DocumentORM).filter(DocumentORM.id.in_(document_ids_to_delete)).delete(
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/orm/query.py", line 3213, in delete
    result = self.session.execute(
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/orm/session.py", line 1714, in execute
    result = conn._execute_20(statement, params or {}, execution_options)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1705, in _execute_20
    return meth(self, args_10style, kwargs_10style, execution_options)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/sql/elements.py", line 333, in _execute_on_connection
    return connection._execute_clauseelement(
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1572, in _execute_clauseelement
    ret = self._execute_context(
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1943, in _execute_context
    self._handle_dbapi_exception(
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 2124, in _handle_dbapi_exception
    util.raise_(
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 208, in raise_
    raise exception
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/engine/base.py", line 1900, in _execute_context
    self.dialect.do_execute(
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/sqlalchemy/engine/default.py", line 736, in do_execute
    cursor.execute(statement, parameters)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/cursors.py", line 148, in execute
    result = self._query(query)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/cursors.py", line 310, in _query
    conn.query(q)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/connections.py", line 548, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/connections.py", line 775, in _read_query_result
    result.read()
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/connections.py", line 1156, in read
    first_packet = self.connection._read_packet()
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/connections.py", line 725, in _read_packet
    packet.raise_for_error()
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/protocol.py", line 221, in raise_for_error
    err.raise_mysql_exception(self._data)
  File "/Users/youbo/miniconda3/envs/docqa/lib/python3.9/site-packages/pymysql/err.py", line 143, in raise_mysql_exception
    raise errorclass(errno, errval)
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1093, "You can't specify target table 'document' for update in FROM clause")
[SQL: DELETE FROM document WHERE document.id IN (SELECT document.id 
FROM document 
WHERE document.`index` = %(index_1)s AND document.id IN (%(id_1_1)s))]
[parameters: {'index_1': 'milvus_data_mysql', 'id_1_1': 'd7cc36dad9ab0403fb9489ec55720d23'}]
(Background on this error at: https://sqlalche.me/e/14/e3q8)
```
**Expected behavior**
A clear and concise description of what you expected to happen.

**Additional context**
Add any other context about the problem here, like document types / preprocessing steps / settings of reader etc.

**To Reproduce**
Steps to reproduce the behavior

**FAQ Check**
- [ ] Have you had a look at [our new FAQ page](https://docs.haystack.deepset.ai/docs/faq)?

**System:**
 - OS: mac m2
 - GPU/CPU: cpu
 - Haystack version (commit or version number): 1.11.0
 - DocumentStore:Milvus2DocumentStore
 - Reader:
 - Retriever:



Discussion:
Hello @youxingtian, thank you for the bug report! Just to clarify: does this error show up on any index or only on empty ones? Does the specified ID exist in the db when you get this error? We're going to try to reproduce this issue in the meantime.
> Hello @youxingtian, thank you for the bug report! Just to clarify: does this error show up on any index or only on empty ones? Does the specified ID exist in the db when you get this error? We're going to try to reproduce this issue in the meantime.

Hi,thank you for your reply! this error show up when I use mysql to store milvus metadata information, and the  ID exist in the db. When I use postgresql to store milvus metadata, it is ok. 

I checked the relevant information,MySQL doesn't allow updating the table you are already using in an inner select as the update criteria.Many other database engines has support for this feature, but MySQL doesn't and you need to workaround the limitation. 



Resolving patch:
diff --git a/haystack/document_stores/sql.py b/haystack/document_stores/sql.py
--- a/haystack/document_stores/sql.py
+++ b/haystack/document_stores/sql.py
@@ -24,7 +24,7 @@
         TypeDecorator,
     )
     from sqlalchemy.ext.declarative import declarative_base
-    from sqlalchemy.orm import relationship, sessionmaker
+    from sqlalchemy.orm import relationship, sessionmaker, aliased
     from sqlalchemy.sql import case, null
 except (ImportError, ModuleNotFoundError) as ie:
     from haystack.utils.import_utils import _optional_component_not_installed
@@ -688,7 +688,8 @@ def delete_documents(
             if ids:
                 document_ids_to_delete = document_ids_to_delete.filter(DocumentORM.id.in_(ids))
 
-            self.session.query(DocumentORM).filter(DocumentORM.id.in_(document_ids_to_delete)).delete(
+            inner_query = document_ids_to_delete.subquery()
+            self.session.query(DocumentORM).filter(DocumentORM.id.in_(aliased(inner_query))).delete(
                 synchronize_session=False
             )
 
@@ -736,7 +737,8 @@ def delete_labels(
             if ids:
                 label_ids_to_delete = label_ids_to_delete.filter(LabelORM.id.in_(ids))
 
-            self.session.query(LabelORM).filter(LabelORM.id.in_(label_ids_to_delete)).delete(synchronize_session=False)
+            inner_query = label_ids_to_delete.subquery()
+            self.session.query(LabelORM).filter(LabelORM.id.in_(aliased(inner_query))).delete(synchronize_session=False)
 
         self.session.commit()
 


Test patch: