str/repr might be broken on RowProxy

Issue #3071 closed
Dustin Oprea created an issue

There are some situations under which the str/repr representations of the returned records are malformed. However, I am unsure of the conditions.

print("0: %s" % (record.__class__))
print("1: %s" % (str(record)))
print("2: %s" % (repr(record)))
print("3: %s" % (dict(record)))
print("4: %s" % (record.items()))

When it works:

0: <class 'sqlalchemy.engine.result.RowProxy'>
1: (5L, 'Dev Client (dustin)', 5L, 1L, '2019-05-27 23:11:47', 0L, 1L)
2: (5L, 'Dev Client (dustin)', 5L, 1L, '2019-05-27 23:11:47', 0L, 1L)
3: {u'certificate_validity_y': 5L, u'certificate_expire_timestamp': '2019-05-27 23:11:47', u'name': 'Dev Client (dustin)', u'can_proxy': 0L, u'is_admin': 1L, u'client_id': 5L, u'allow_api': 1L}
4: [(u'client_id', 5L), (u'name', 'Dev Client (dustin)'), (u'certificate_validity_y', 5L), (u'allow_api', 1L), (u'certificate_expire_timestamp', '2019-05-27 23:11:47'), (u'can_proxy', 0L), (u'is_admin', 1L)]

When it's broken:

0: <class 'sqlalchemy.engine.result.RowProxy'>
1: (1L,)
2: (1L,)
3: {u'affected': 1L}
4: [(u'affected', 1L)]

I also used "xyz" as the column name, but it didn't make a difference:

0: <class 'sqlalchemy.engine.result.RowProxy'>
1: (1L,)
2: (1L,)
3: {u'xyz': 1L}
4: [(u'xyz', 1L)]

I am using MySQL. It happens on latest (0.9.5).

Comments (4)

  1. Mike Bayer repo owner

    I'm staring at this pretty hard, maybe it's because this is the first thing I'm looking at this morning before coffee, but I'm not seeing what's malformed? Can you clue me in? thanks.

  2. Dustin Oprea reporter

    The str/repr of the row sometimes shows the proper names of the columns and their values, and sometimes doesn't. Compare the first and second outputs.

  3. Mike Bayer repo owner

    how would I know that "affected" is not the name of the column? I see this:

    1. the class repr of the row, this is correct
    2. a tuple of the values in each column, no column names
    3. a tuple of the values in each column, no column names
    4. a dictionary display of the row, includes column names
    5. a list of tuples display of the row, includes column names

    I can produce the identical output with this script:

    class MySimulatedRowProxy(object):
        def __init__(self, data):
            self.data = data
    
        def __iter__(self):
            return iter(self.data)
    
        def items(self):
            return self.data
    
        def __str__(self):
            return str(tuple([value for key, value in self.data]))
    
        def __repr__(self):
            return str(tuple([value for key, value in self.data]))
    
    r1 = MySimulatedRowProxy([(u'client_id', 5L), (u'name', 'Dev Client (dustin)'),
                            (u'certificate_validity_y', 5L), (u'allow_api', 1L),
                            (u'certificate_expire_timestamp', '2019-05-27 23:11:47'),
                            (u'can_proxy', 0L), (u'is_admin', 1L)])
    r2 = MySimulatedRowProxy([(u'affected', 1L)])
    
    def print_(record):
        print("0: %s" % (record.__class__))
        print("1: %s" % (str(record)))
        print("2: %s" % (repr(record)))
        print("3: %s" % (dict(record)))
        print("4: %s" % (record.items()))
    
    print_(r1)
    print_(r2)
    

    output:

    #!
    
    0: <class '__main__.MySimulatedRowProxy'>
    1: (5L, 'Dev Client (dustin)', 5L, 1L, '2019-05-27 23:11:47', 0L, 1L)
    2: (5L, 'Dev Client (dustin)', 5L, 1L, '2019-05-27 23:11:47', 0L, 1L)
    3: {u'certificate_validity_y': 5L, u'certificate_expire_timestamp': '2019-05-27 23:11:47', u'name': 'Dev Client (dustin)', u'can_proxy': 0L, u'is_admin': 1L, u'client_id': 5L, u'allow_api': 1L}
    4: [(u'client_id', 5L), (u'name', 'Dev Client (dustin)'), (u'certificate_validity_y', 5L), (u'allow_api', 1L), (u'certificate_expire_timestamp', '2019-05-27 23:11:47'), (u'can_proxy', 0L), (u'is_admin', 1L)]
    0: <class '__main__.MySimulatedRowProxy'>
    1: (1L,)
    2: (1L,)
    3: {u'affected': 1L}
    4: [(u'affected', 1L)]
    

    can you confirm that's the identical output, some dictionary ordering notwithstanding?

  4. Log in to comment