Issue 1:
Migrated issue, originally created by Anonymous

Not sure what the precise problem is here, but on my system I get the following exception with the current sqlalchemy trunk from Subversion (revision 1344)

[15:27:20,845](2006-04-27) [engine](engine): DELETE FROM managers WHERE managers.person_id = %(person_id)s
[15:27:20,845](2006-04-27) [engine](engine): [1}, {'person_id': 2}]({'person_id':)
Traceback (most recent call last):
File "polymorph2.py", line 130, in ?
objectstore.commit()
File "build/bdist.darwin-8.6.0-Power_Macintosh/egg/sqlalchemy/mapping/objectstore.py", line 250, in commit
File "build/bdist.darwin-8.6.0-Power_Macintosh/egg/sqlalchemy/mapping/objectstore.py", line 81, in flush
File "build/bdist.darwin-8.6.0-Power_Macintosh/egg/sqlalchemy/mapping/unitofwork.py", line 249, in flush
File "build/bdist.darwin-8.6.0-Power_Macintosh/egg/sqlalchemy/mapping/unitofwork.py", line 374, in execute
File "build/bdist.darwin-8.6.0-Power_Macintosh/egg/sqlalchemy/mapping/unitofwork.py", line 540, in execute
File "build/bdist.darwin-8.6.0-Power_Macintosh/egg/sqlalchemy/mapping/unitofwork.py", line 540, in execute
File "build/bdist.darwin-8.6.0-Power_Macintosh/egg/sqlalchemy/mapping/unitofwork.py", line 544, in execute
File "build/bdist.darwin-8.6.0-Power_Macintosh/egg/sqlalchemy/mapping/mapper.py", line 661, in delete_obj
sqlalchemy.exceptions.CommitError: ConcurrencyError - updated rowcount 1 does not match number of objects updated 2

Issue 2:
Describe the bug

The column name values is causing a bug when doing an upsert with MySQL (using pymysql).

For testing purposes, you can change the column name in the variable values_column_name to something else than values and then you will see that no errors occur.

To Reproduce

from sqlalchemy import create_engine, Column, Integer, MetaData, Table, Text
from sqlalchemy.dialects.mysql.dml import insert as mysql_insert

# config
table_name = 'test_upsert_mysql'
engine = create_engine(CONNECTION_STRING) # please put your connection string to a MySQL database here
engine.execute(f'DROP TABLE IF EXISTS {table_name};') # reset previous tests

values_column_name = 'values' # change this to anything else than "values" and there shall be no bug

# table model
table = Table('test_upsert_mysql',
MetaData(bind=engine),
Column('profileid', Integer(), primary_key=True, nullable=False),
Column(values_column_name, Integer()))
table.create()

# test upsert
values = [{'profileid':1, values_column_name:1}]
insert_stmt = mysql_insert(table).values(values)
upsert = insert_stmt.on_duplicate_key_update({values_column_name:getattr(insert_stmt.inserted, values_column_name)})
engine.execute(upsert)

Error

---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-5-6e7be1d0a0c8> in <module>
20 insert_stmt = mysql_insert(table).values(values)
21 upsert = insert_stmt.on_duplicate_key_update({values_column_name:getattr(insert_stmt.inserted, values_column_name)})
---> 22 engine.execute(upsert)

<string> in execute(self, statement, *multiparams, **params)

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/util/deprecations.py in warned(fn, *args, **kwargs)
388 if not skip_warning:
389 _warn_with_version(message, version, wtype, stacklevel=3)
--> 390 return fn(*args, **kwargs)
391
392 doc = func.__doc__ is not None and func.__doc__ or ""

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/engine/base.py in execute(self, statement, *multiparams, **params)
3105 """
3106 connection = self.connect(close_with_result=True)
-> 3107 return connection.execute(statement, *multiparams, **params)
3108
3109 @util.deprecated_20(

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/engine/base.py in execute(self, statement, *multiparams, **params)
1260 )
1261 else:
-> 1262 return meth(self, multiparams, params, _EMPTY_EXECUTION_OPTS)
1263
1264 def _execute_function(self, func, multiparams, params, execution_options):

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/sql/elements.py in _execute_on_connection(self, connection, multiparams, params, execution_options, _force)
322 ):
323 if _force or self.supports_execution:
--> 324 return connection._execute_clauseelement(
325 self, multiparams, params, execution_options
326 )

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _execute_clauseelement(self, elem, multiparams, params, execution_options)
1449 linting=self.dialect.compiler_linting | compiler.WARN_LINTING,
1450 )
-> 1451 ret = self._execute_context(
1452 dialect,
1453 dialect.execution_ctx_cls._init_compiled,

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _execute_context(self, dialect, constructor, statement, parameters, execution_options, *args, **kw)
1811
1812 except BaseException as e:
-> 1813 self._handle_dbapi_exception(
1814 e, statement, parameters, cursor, context
1815 )

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
1996 )
1997 else:
-> 1998 util.raise_(exc_info[1], with_traceback=exc_info[2])
1999
2000 finally:

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/util/compat.py in raise_(***failed resolving arguments***)
205
206 try:
--> 207 raise exception
208 finally:
209 # credit to

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/engine/base.py in _execute_context(self, dialect, constructor, statement, parameters, execution_options, *args, **kw)
1768 break
1769 if not evt_handled:
-> 1770 self.dialect.do_execute(
1771 cursor, statement, parameters, context
1772 )

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/sqlalchemy/engine/default.py in do_execute(self, cursor, statement, parameters, context)
715
716 def do_execute(self, cursor, statement, parameters, context=None):
--> 717 cursor.execute(statement, parameters)
718
719 def do_execute_no_params(self, cursor, statement, context=None):

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/cursors.py in execute(self, query, args)
159 pass
160
--> 161 query = self.mogrify(query, args)
162
163 result = self._query(query)

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/cursors.py in mogrify(self, query, args)
138
139 if args is not None:
--> 140 query = query % self._escape_args(args, conn)
141
142 return query

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/cursors.py in _escape_args(self, args, conn)
118 args = {ensure_bytes(key): ensure_bytes(val) for
119 (key, val) in args.items()}
--> 120 return {key: conn.literal(val) for (key, val) in args.items()}
121 else:
122 # If it's not a dictionary let's try escaping it anyways.

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/cursors.py in <dictcomp>(.0)
118 args = {ensure_bytes(key): ensure_bytes(val) for
119 (key, val) in args.items()}
--> 120 return {key: conn.literal(val) for (key, val) in args.items()}
121 else:
122 # If it's not a dictionary let's try escaping it anyways.

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/connections.py in literal(self, obj)
467 Non-standard, for internal use; do not use this in your applications.
468 """
--> 469 return self.escape(obj, self.encoders)
470
471 def escape_string(self, s):

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/connections.py in escape(self, obj, mapping)
460 ret = "_binary" + ret
461 return ret
--> 462 return converters.escape_item(obj, self.charset, mapping=mapping)
463
464 def literal(self, obj):

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/converters.py in escape_item(val, charset, mapping)
25 val = encoder(val, charset, mapping)
26 else:
---> 27 val = encoder(val, mapping)
28 return val
29

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/converters.py in escape_unicode(value, mapping)
121
122 def escape_unicode(value, mapping=None):
--> 123 return u"'%s'" % _escape_unicode(value)
124
125 def escape_str(value, mapping=None):

~/anaconda3/envs/pangres-dev/lib/python3.8/site-packages/pymysql/converters.py in _escape_unicode(value, mapping)
76 Value should be unicode
77 """
---> 78 return value.translate(_escape_table)
79
80 if PY2:

AttributeError: 'function' object has no attribute 'translate'

Versions.

OS: Pop!_OS 20.04 LTS

Python: 3.8.5

SQLAlchemy: 1.4.18

Database: MySQL

DBAPI: pymysql 0.10.1

Additional context

This came to my attention via an issue thtat a user of my library pangres created.

Have a nice day!