:ticket:`3292`
+.. _change_gh_231:
+
+Negative integer indexes accommodated by Core result rows
+---------------------------------------------------------
+
+The :class:`.RowProxy` object now accomodates single negative integer indexes
+like a regular Python sequence, both in the pure Python and C-extension
+version. Previously, negative values would only work in slices::
+
+ >>> from sqlalchemy import create_engine
+ >>> e = create_engine("sqlite://")
+ >>> row = e.execute("select 1, 2, 3").first()
+ >>> row[-1], row[-2], row[1], row[-2:2]
+ 3 2 2 (2,)
+
.. _change_3095:
The ``Enum`` type now does in-Python validation of values
# implementation to avoid an expensive
# isinstance(key, util.int_types) in the most common
# case path
+
+ len_raw = len(raw)
+
self._keymap.update([
(elem[0], (elem[3], elem[4], elem[0]))
for elem in raw
] + [
- (elem[0] - num_ctx_cols, (elem[3], elem[4], elem[0]))
+ (elem[0] - len_raw, (elem[3], elem[4], elem[0]))
for elem in raw
])
{'key': (None, None, 0), 0: (None, None, 0)})
assert isinstance(row, collections.Sequence)
- def test_rowproxy_getitem(self):
- metadata = MetaData()
- metadata.bind = 'sqlite://'
- values = Table('users', metadata,
+ @testing.provide_metadata
+ def test_rowproxy_getitem_indexes_compiled(self):
+ values = Table('users', self.metadata,
Column('key', String(10), primary_key=True),
Column('value', String(10)))
values.create()
- values.insert().execute(key='One', value='Uno')
- row = values.select().execute().fetchone()
-
- assert row['key'] == 'One'
- assert row['value'] == 'Uno'
- assert row[0] == 'One'
- assert row[1] == 'Uno'
- assert row[-2] == 'One'
- assert row[-1] == 'Uno'
- assert row[1:0:-1] == ('Uno',)
+ testing.db.execute(values.insert(), dict(key='One', value='Uno'))
+ row = testing.db.execute(values.select()).first()
+ eq_(row['key'], 'One')
+ eq_(row['value'], 'Uno')
+ eq_(row[0], 'One')
+ eq_(row[1], 'Uno')
+ eq_(row[-2], 'One')
+ eq_(row[-1], 'Uno')
+ eq_(row[1:0:-1], ('Uno',))
+
+ def test_rowproxy_getitem_indexes_raw(self):
+ row = testing.db.execute("select 'One' as key, 'Uno' as value").first()
+ eq_(row['key'], 'One')
+ eq_(row['value'], 'Uno')
+ eq_(row[0], 'One')
+ eq_(row[1], 'Uno')
+ eq_(row[-2], 'One')
+ eq_(row[-1], 'Uno')
+ eq_(row[1:0:-1], ('Uno',))
@testing.requires.cextensions
def test_row_c_sequence_check(self):