<p dir="auto"><strong>Migrated issue, originally created by Softbreakers (<a href="https://github.com/softbreakers">@softbreakers</a>)</strong></p>
<p dir="auto">From sqlalchemy.dialects.mysql.base code comments:</p>
<p dir="auto"><em><code class="notranslate">ON DUPLICATE KEY UPDATE</code> is used to perform an update of the already<br>
existing row, using any combination of new values as well as values<br>
from the proposed insertion.</em></p>
<p dir="auto">But in case of duplicate, MySQL 5.7 supports update using new values, values from proposed insertion <strong>and values from the already existing row</strong>.</p>
<p dir="auto"><a href="https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html" rel="nofollow">For example</a>:<br>
<em>INSERT INTO t1 (a,b,c) VALUES (1,2,3)<br>
ON DUPLICATE KEY UPDATE c=c+1;</em></p>
<p dir="auto">Suppose a table with two columns: 'name' as string and 'counter' as integer.<br>
If I try something like:</p>
<p dir="auto"><em>insert_stmt = insert(tableobject)</em></p>
<p dir="auto"><em>on_duplicate_key_stmt = insert_stmt.on_duplicate_key_update(counter='counter+1')</em></p>
<p dir="auto"><em>values =[{'name':valname, 'counter':1, }]</em></p>
<p dir="auto"><em>conexBD.execute(on_duplicate_key_stmt, values)</em></p>
<p dir="auto">The engine assumes 'counter+1' as a literal value, and generates a SQL statement using quotes for the UPDATE part, like:</p>
<p dir="auto"><em>'INSERT INTO mytable (name, counter) VALUES (%s, %s) ON DUPLICATE KEY UPDATE counter = %s'] [parameters: ('any_name', 1, 'counter+1')]</em></p>
<p dir="auto">Which results in a exception message like:</p>
<p dir="auto"><em>(1366, "Incorrect integer value: 'counter+1' for column 'counter' at row 1")</em></p>
<p dir="auto">When having a table name <code class="notranslate">My_Table</code> passed to</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="sqlalchemy.sql.schema.MetaData.reflect(only=[quoted_name(&quot;My_Table&quot;, False)])"><pre class="notranslate"><span class="pl-s1">sqlalchemy</span>.<span class="pl-s1">sql</span>.<span class="pl-s1">schema</span>.<span class="pl-v">MetaData</span>.<span class="pl-en">reflect</span>(<span class="pl-s1">only</span><span class="pl-c1">=</span>[<span class="pl-en">quoted_name</span>(<span class="pl-s">"My_Table"</span>, <span class="pl-c1">False</span>)])</pre></div>
<p dir="auto">I get the false error, that the table does not exist if the case does not match. For example if pandas tries to drop a table when replacing it:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="File &quot;***\lib\site-packages\pandas\io\sql.py&quot;, line 1366, in drop_table
    self.meta.reflect(only=[table_name], schema=schema)
  File &quot;***\lib\site-packages\sqlalchemy\sql\schema.py&quot;, line 4268, in reflect
    &quot;in %r%s: (%s)&quot; % (bind.engine, s, &quot;, &quot;.join(missing))
sqlalchemy.exc.InvalidRequestError: Could not reflect: requested table(s) not available in Engine(****) schema 'myschema': (My_Table)"><pre class="notranslate"><code class="notranslate">File "***\lib\site-packages\pandas\io\sql.py", line 1366, in drop_table
    self.meta.reflect(only=[table_name], schema=schema)
  File "***\lib\site-packages\sqlalchemy\sql\schema.py", line 4268, in reflect
    "in %r%s: (%s)" % (bind.engine, s, ", ".join(missing))
sqlalchemy.exc.InvalidRequestError: Could not reflect: requested table(s) not available in Engine(****) schema 'myschema': (My_Table)
</code></pre></div>
<p dir="auto">The cause of this is that within the <code class="notranslate">MetaData.reflect()</code> method <code class="notranslate">quoted_name</code> objects are not treated properly. Regarding the error above the error caused at:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="            else:
                missing = [name for name in only if name not in available]
                if missing:
                    s = schema and (&quot; schema '%s'&quot; % schema) or &quot;&quot;
                    raise exc.InvalidRequestError(
                        &quot;Could not reflect: requested table(s) not available &quot;
                        &quot;in %r%s: (%s)&quot; % (bind.engine, s, &quot;, &quot;.join(missing))
                    )"><pre class="notranslate">            <span class="pl-s1">else</span>:
                <span class="pl-s1">missing</span> <span class="pl-c1">=</span> [<span class="pl-s1">name</span> <span class="pl-k">for</span> <span class="pl-s1">name</span> <span class="pl-c1">in</span> <span class="pl-s1">only</span> <span class="pl-k">if</span> <span class="pl-s1">name</span> <span class="pl-c1">not</span> <span class="pl-c1">in</span> <span class="pl-s1">available</span>]
                <span class="pl-k">if</span> <span class="pl-s1">missing</span>:
                    <span class="pl-s1">s</span> <span class="pl-c1">=</span> <span class="pl-s1">schema</span> <span class="pl-c1">and</span> (<span class="pl-s">" schema '%s'"</span> <span class="pl-c1">%</span> <span class="pl-s1">schema</span>) <span class="pl-c1">or</span> <span class="pl-s">""</span>
                    <span class="pl-k">raise</span> <span class="pl-s1">exc</span>.<span class="pl-v">InvalidRequestError</span>(
                        <span class="pl-s">"Could not reflect: requested table(s) not available "</span>
                        <span class="pl-s">"in %r%s: (%s)"</span> <span class="pl-c1">%</span> (<span class="pl-s1">bind</span>.<span class="pl-s1">engine</span>, <span class="pl-s1">s</span>, <span class="pl-s">", "</span>.<span class="pl-en">join</span>(<span class="pl-s1">missing</span>))
                    )</pre></div>
<p dir="auto">The list <code class="notranslate">available</code> contains all the table names in lowercase since they were unquoted on the database and have been normalized to SQLAlchemys convention for case insensitive.<br>
The table names stored in only are not normalized and a comparison between <code class="notranslate">quoted_name("My_Table", False)</code> and a string in the <code class="notranslate">available</code> list <code class="notranslate">my_table</code> evaluated to <code class="notranslate">False</code> thus causing SQLAlchemy telling me that the table is missing.</p>
<p dir="auto">I think somewhere in there the dialects <code class="notranslate">normalize_name</code> needs to be called for the tables in <code class="notranslate">only</code> or the comparison has to be done in another way since one should not compare <code class="notranslate">quoted_name</code> objects and strings like that.</p>