unknown numeric is received.
- psycopg2/pg8000 dialects now aware of REAL[], FLOAT[],
DOUBLE_PRECISION[], NUMERIC[] return types without
raising an exception.
- introducing testing.provide_metadata for all these stupid little
create/drop tests
has been changed. Thanks to Kumar McMillan for the patch.
[ticket:1071]
+ - Repaired missing import in psycopg2._PGNumeric type when
+ unknown numeric is received.
+
+ - psycopg2/pg8000 dialects now aware of REAL[], FLOAT[],
+ DOUBLE_PRECISION[], NUMERIC[] return types without
+ raising an exception.
+
- oracle
- Now using cx_oracle output converters so that the
DBAPI returns natively the kinds of values we prefer:
class _PGNumeric(sqltypes.Numeric):
def result_processor(self, dialect, coltype):
if self.asdecimal:
- if coltype in (700, 701):
+ if coltype in (700, 701, 1021, 1022):
return processors.to_decimal_processor_factory(decimal.Decimal)
- elif coltype == 1700:
+ elif coltype in (1700, 1231):
# pg8000 returns Decimal natively for 1700
return None
else:
raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
else:
- if coltype in (700, 701):
+ if coltype in (700, 701, 1021, 1022):
# pg8000 returns float natively for 701
return None
- elif coltype == 1700:
+ elif coltype in (1700, 1231):
return processors.to_float
else:
raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
import decimal
import logging
-from sqlalchemy import util
+from sqlalchemy import util, exc
from sqlalchemy import processors
from sqlalchemy.engine import base, default
from sqlalchemy.sql import expression
def result_processor(self, dialect, coltype):
if self.asdecimal:
- if coltype in (700, 701):
+ if coltype in (700, 701, 1021, 1022):
return processors.to_decimal_processor_factory(decimal.Decimal)
- elif coltype == 1700:
+ elif coltype in (1700, 1231):
# pg8000 returns Decimal natively for 1700
return None
else:
raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
else:
- if coltype in (700, 701):
+ if coltype in (700, 701, 1021, 1022):
# pg8000 returns float natively for 701
return None
- elif coltype == 1700:
+ elif coltype in (1700, 1231):
return processors.to_float
else:
raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
for column_values in rows])
table.append_ddl_listener('after-create', onload)
+def provide_metadata(fn):
+ """Provides a bound MetaData object for a single test,
+ drops it afterwards."""
+ def maybe(*args, **kw):
+ metadata = schema.MetaData(db)
+ context = dict(fn.func_globals)
+ context['metadata'] = metadata
+ # jython bug #1034
+ rebound = types.FunctionType(
+ fn.func_code, context, fn.func_name, fn.func_defaults,
+ fn.func_closure)
+ try:
+ return rebound(*args, **kw)
+ finally:
+ metadata.drop_all()
+ return function_named(maybe, fn.__name__)
+
def resolve_artifact_names(fn):
"""Decorator, augment function globals with tables and classes.
).scalar()
eq_(round_decimal(ret, 9), result)
-
+ @testing.provide_metadata
+ def test_arrays(self):
+ t1 = Table('t', metadata,
+ Column('x', postgresql.ARRAY(Float)),
+ Column('y', postgresql.ARRAY(postgresql.REAL)),
+ Column('z', postgresql.ARRAY(postgresql.DOUBLE_PRECISION)),
+ Column('q', postgresql.ARRAY(Numeric))
+ )
+ metadata.create_all()
+ t1.insert().execute(x=[5], y=[5], z=[6], q=[6.4])
+ row = t1.select().execute().first()
+ eq_(
+ row,
+ ([5], [5], [6], [decimal.Decimal("6.4")])
+ )
class EnumTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
__only_on__ = 'postgresql'
else:
exception_cls = eng.dialect.dbapi.ProgrammingError
assert_raises(exception_cls, eng.execute, "show transaction isolation level")
-
-
+
+ @testing.only_on('postgresql+psycopg2',
+ "this assertion isn't used on others, "
+ "except pg8000 which circumvents it")
+ def test_numeric_raise(self):
+ stmt = text("select 'hi' as hi", typemap={'hi':Numeric})
+ assert_raises(
+ exc.InvalidRequestError,
+ testing.db.execute, stmt
+ )
+
class TimezoneTest(TestBase):
"""Test timezone-aware datetimes.