Hi, I found what I think to be a bug in the bulk save objects method. The 
following raises an exception:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Obj(Base):
__tablename__ = 'obj_bulk_test'

id = Column(Integer, primary_key=True)
date = Column(Date, nullable=False)

if __name__ == '__main__':
e = create_engine('mysql+pymysql://user:password@localhost/test')
Base.metadata.create_all(e)
s = Session(e)

s.add_all([Obj(date=func.now()) for i in range(10)])

s.commit()

objs = s.query(Obj).all()

for o in objs:
o.date = func.current_date()

s.bulk_save_objects(objs)

s.commit()

I got the following exception

Traceback (most recent call last):
  File "C:\Python35\lib\site-packages\sqlalchemy\sql\elements.py", line 
676, in __getattr__
    return getattr(self.comparator, key)
AttributeError: 'Comparator' object has no attribute 'translate'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "sqa_bulk_save_func.py", line 28, in <module>
    s.bulk_save_objects(objs)
  File "C:\Python35\lib\site-packages\sqlalchemy\orm\session.py", line 
2338, in bulk_save_objects
    return_defaults, update_changed_only, False)
  File "C:\Python35\lib\site-packages\sqlalchemy\orm\session.py", line 
2502, in _bulk_save_mappings
    transaction.rollback(_capture_exception=True)
  File "C:\Python35\lib\site-packages\sqlalchemy\util\langhelpers.py", line 
60, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "C:\Python35\lib\site-packages\sqlalchemy\util\compat.py", line 186, 
in reraise
    raise value
  File "C:\Python35\lib\site-packages\sqlalchemy\orm\session.py", line 
2493, in _bulk_save_mappings
    isstates, update_changed_only)
  File "C:\Python35\lib\site-packages\sqlalchemy\orm\persistence.py", line 
123, in _bulk_update
    bookkeeping=False)
  File "C:\Python35\lib\site-packages\sqlalchemy\orm\persistence.py", line 
732, in _emit_update_statements
    execute(statement, multiparams)
  File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 945, 
in execute
    return meth(self, multiparams, params)
  File "C:\Python35\lib\site-packages\sqlalchemy\sql\elements.py", line 
263, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 
1053, in _execute_clauseelement
    compiled_sql, distilled_params
  File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 
1189, in _execute_context
    context)
  File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 
1396, in _handle_dbapi_exception
    util.reraise(*exc_info)
  File "C:\Python35\lib\site-packages\sqlalchemy\util\compat.py", line 186, 
in reraise
    raise value
  File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 
1159, in _execute_context
    context)
  File 
"C:\Python35\lib\site-packages\sqlalchemy\dialects\mysql\mysqldb.py", line 
95, in do_executemany
    rowcount = cursor.executemany(statement, parameters)
  File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 195, in 
executemany
    self.rowcount = sum(self.execute(query, arg) for arg in args)
  File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 195, in 
<genexpr>
    self.rowcount = sum(self.execute(query, arg) for arg in args)
  File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 164, in 
execute
    query = self.mogrify(query, args)
  File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 143, in 
mogrify
    query = query % self._escape_args(args, conn)
  File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 123, in 
_escape_args
    return dict((key, conn.literal(val)) for (key, val) in args.items())
  File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 123, in 
<genexpr>
    return dict((key, conn.literal(val)) for (key, val) in args.items())
  File "C:\Python35\lib\site-packages\pymysql\connections.py", line 800, in 
literal
    return self.escape(obj, self.encoders)
  File "C:\Python35\lib\site-packages\pymysql\connections.py", line 793, in 
escape
    return escape_item(obj, self.charset, mapping=mapping)
  File "C:\Python35\lib\site-packages\pymysql\converters.py", line 27, in 
escape_item
    val = encoder(val, mapping)
  File "C:\Python35\lib\site-packages\pymysql\converters.py", line 110, in 
escape_unicode
    return u"'%s'" % _escape_unicode(value)
  File "C:\Python35\lib\site-packages\pymysql\converters.py", line 73, in 
_escape_unicode
    return value.translate(_escape_table)
  File "C:\Python35\lib\site-packages\sqlalchemy\sql\elements.py", line 
682, in __getattr__
    key)
AttributeError: Neither 'now' object nor 'Comparator' object has an 
attribute 'translate'

I thought that the func methods simply rendered text like CURRENT_DATE, but 
sqlalchemy echoes something like this

UPDATE obj_bulk_test SET date=%(date)s WHERE obj_bulk_test.id = 
%(obj_bulk_test_id)s
2017-04-28 13:10:44,551 INFO sqlalchemy.engine.base.Engine 
({'obj_bulk_test_id': 1, 'date': <sqlalchemy.sql.functions.now at 
0x34a63b0; now>}, {'obj_bulk_test_id': 2, 'date': 
<sqlalchemy.sql.functions.now at 0x34a65b0; now>}, {'obj_bulk_test_id': 3, 
'date': <sqlalchemy.sql.functions.now at 0x34a6e90; now>}, 
{'obj_bulk_test_id': 4, 'date': <sqlalchemy.sql.functions.now at 0x34a6650; 
now>}, {'obj_bulk_test_id': 5, 'date': <sqlalchemy.sql.functions.now at 
0x34a66d0; now>}, {'obj_bulk_test_id': 6, 'date': 
<sqlalchemy.sql.functions.now at 0x34a6cf0; now>}, {'obj_bulk_test_id': 7, 
'date': <sqlalchemy.sql.functions.now at 0x34a6c50; now>}, 
{'obj_bulk_test_id': 8, 'date': <sqlalchemy.sql.functions.now at 0x34a6bb0; 
now>}, {'obj_bulk_test_id': 9, 'date': <sqlalchemy.sql.functions.now at 
0x34a6af0; now>}, {'obj_bulk_test_id': 10, 'date': 
<sqlalchemy.sql.functions.now at 0x34a69d0; now>})

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to