ellipses_string in langhelpers.py raises StatementError for non-string values

Issue #3346 resolved
Sebastian Elsner created an issue

Using 1.0b4. If "value" is not a string, this will raise an exception, which results in a StatementError, when happening in a flush.

def ellipses_string(value, len_=25):
    if len(value) > len_:
        return "%s..." % value[0:len_]
    else:
        return value

using:

if len(str(value)) > len_:

instead, fixes the problem for me, though I do not know if this is a good way.

Comments (6)

  1. Sebastian Elsner reporter

    After a bit more investigation: This happens because I have a "Unicode" column, which I was setting to an "int" in init. Of course I get a deprecation warning, but the ellipses_string function does not deal well with ints.

  2. Mike Bayer repo owner

    any chance you can illustrate this in some kind of test since I'll need to add a test to test/engine/test_execute.py in any case. also is this py3k ?

  3. Sebastian Elsner reporter

    This is with ancient Python 2.6.6 on CentOS 6.5 64bit

    from sqlalchemy import Column, Integer, Unicode, create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker
    
    
    Base = declarative_base()
    
    
    class Entity(Base):
        __tablename__ = 'entity'
        id = Column(Integer, primary_key=True)
        name = Column(Unicode(1))
    
        def __init__(self):
            self.name = 0
    
    
    engine = create_engine('mysql://test:test@localhost/test')
    
    
    Session = sessionmaker()
    Session.configure(bind=engine)
    Base.metadata.create_all(engine)
    
    s = Session()
    e = Entity()
    s.add(e)
    s.flush()
    

    Result: sqlalchemy.exc.StatementError: (exceptions.TypeError) object of type 'int' has no len() [SQL: u'INSERT INTO entity (name) VALUES (%s)'] [parameters: [{'name': 0}]]

    I tried with a in-memory SQLite db, but it did not happen, seems to be MySQL specific.

  4. Mike Bayer repo owner

    not every dialect uses the SQLAlchemy-side processing of strings. But this is sending a total non-string into a string. The error should be fixed but really this should totally raise 100%, in fact.

  5. Mike Bayer repo owner
    • The warning emitted by the unicode type for a non-unicode type has been liberalized to warn for values that aren't even string values, such as integers; previously, the updated warning system of 1.0 made use of string formatting operations which would raise an internal TypeError. While these cases should ideally raise totally, some backends like SQLite and MySQL do accept them and are potentially in use by legacy code, not to mention that they will always pass through if unicode conversion is turned off for the target backend. fixes #3346

    → <<cset 5ed49f38c372>>

  6. Mike Bayer repo owner

    well it's 1.0 only because we didn't format that string before, so it's a regression and I've just made the formatting more resilient.

  7. Log in to comment