diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-27 13:40:55 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-27 13:40:55 -0500 |
| commit | 17f4b8f829df4bd6e65dd845fde6a75fe9178561 (patch) | |
| tree | 31bd99b1047e3d582242818041f0aa517eee214b | |
| parent | ff47daf233894fdc3735c78b1a1170f96cfcd7e8 (diff) | |
| parent | 92a1426c06c49f5b3db8cc41afe0ed92e8631972 (diff) | |
| download | sqlalchemy-17f4b8f829df4bd6e65dd845fde6a75fe9178561.tar.gz | |
Merge branch 'master' into rel_0_9
| -rw-r--r-- | doc/build/changelog/changelog_08.rst | 24 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/firebird/base.py | 3 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/firebird/kinterbasdb.py | 9 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/requirements.py | 14 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/suite/test_insert.py | 16 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/suite/test_reflection.py | 6 | ||||
| -rw-r--r-- | test/dialect/test_firebird.py | 9 | ||||
| -rw-r--r-- | test/requirements.py | 32 |
8 files changed, 105 insertions, 8 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index 0f3737d53..2e6bc153c 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -12,6 +12,30 @@ :version: 0.8.5 .. change:: + :tags: bug, firebird + :versions: 0.9.0b2 + :tickets: 2897 + + The firebird dialect will quote identifiers which begin with an + underscore. Courtesy Treeve Jelbert. + + .. change:: + :tags: bug, firebird + :versions: 0.9.0b2 + + Fixed bug in Firebird index reflection where the columns within the + index were not sorted correctly; they are now sorted + in order of RDB$FIELD_POSITION. + + .. change:: + :tags: bug, firebird + :versions: 0.9.0b2 + + The "asdecimal" flag used with the :class:`.Float` type will now + work with Firebird dialects; previously the decimal conversion was + not occurring. + + .. change:: :tags: bug, mssql, pymssql :versions: 0.9.0b2 :pullreq: github:51 diff --git a/lib/sqlalchemy/dialects/firebird/base.py b/lib/sqlalchemy/dialects/firebird/base.py index dcaa68f4e..777d3ce26 100644 --- a/lib/sqlalchemy/dialects/firebird/base.py +++ b/lib/sqlalchemy/dialects/firebird/base.py @@ -359,6 +359,7 @@ class FBIdentifierPreparer(sql.compiler.IdentifierPreparer): """Install Firebird specific reserved words.""" reserved_words = RESERVED_WORDS + illegal_initial_characters = compiler.ILLEGAL_INITIAL_CHARACTERS.union(['_']) def __init__(self, dialect): super(FBIdentifierPreparer, self).__init__(dialect, omit_schema=True) @@ -700,7 +701,7 @@ class FBDialect(default.DefaultDialect): ic.rdb$index_name WHERE ix.rdb$relation_name=? AND ix.rdb$foreign_key IS NULL AND rdb$relation_constraints.rdb$constraint_type IS NULL - ORDER BY index_name, field_name + ORDER BY index_name, ic.rdb$field_position """ c = connection.execute(qry, [self.denormalize_name(table_name)]) diff --git a/lib/sqlalchemy/dialects/firebird/kinterbasdb.py b/lib/sqlalchemy/dialects/firebird/kinterbasdb.py index c8d8e986f..4b083deeb 100644 --- a/lib/sqlalchemy/dialects/firebird/kinterbasdb.py +++ b/lib/sqlalchemy/dialects/firebird/kinterbasdb.py @@ -42,7 +42,7 @@ from re import match import decimal -class _FBNumeric_kinterbasdb(sqltypes.Numeric): +class _kinterbasdb_numeric(object): def bind_processor(self, dialect): def process(value): if isinstance(value, decimal.Decimal): @@ -51,6 +51,12 @@ class _FBNumeric_kinterbasdb(sqltypes.Numeric): return value return process +class _FBNumeric_kinterbasdb(_kinterbasdb_numeric, sqltypes.Numeric): + pass + +class _FBFloat_kinterbasdb(_kinterbasdb_numeric, sqltypes.Float): + pass + class FBExecutionContext_kinterbasdb(FBExecutionContext): @property @@ -74,6 +80,7 @@ class FBDialect_kinterbasdb(FBDialect): FBDialect.colspecs, { sqltypes.Numeric: _FBNumeric_kinterbasdb, + sqltypes.Float: _FBFloat_kinterbasdb, } ) diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py index e48fa2c00..3e48ba026 100644 --- a/lib/sqlalchemy/testing/requirements.py +++ b/lib/sqlalchemy/testing/requirements.py @@ -139,6 +139,20 @@ class SuiteRequirements(Requirements): return exclusions.open() @property + def fetch_rows_post_commit(self): + """target platform will allow cursor.fetchone() to proceed after a + COMMIT. + + Typically this refers to an INSERT statement with RETURNING which + is invoked within "autocommit". If the row can be returned + after the autocommit, then this rule can be open. + + """ + + return exclusions.open() + + + @property def empty_inserts(self): """target platform supports INSERT with no values, i.e. INSERT DEFAULT VALUES or equivalent.""" diff --git a/lib/sqlalchemy/testing/suite/test_insert.py b/lib/sqlalchemy/testing/suite/test_insert.py index 21141f244..deda63b24 100644 --- a/lib/sqlalchemy/testing/suite/test_insert.py +++ b/lib/sqlalchemy/testing/suite/test_insert.py @@ -172,7 +172,8 @@ class ReturningTest(fixtures.TablesTest): Column('data', String(50)) ) - def test_explicit_returning_pk(self): + @requirements.fetch_rows_post_commit + def test_explicit_returning_pk_autocommit(self): engine = config.db table = self.tables.autoinc_pk r = engine.execute( @@ -184,6 +185,19 @@ class ReturningTest(fixtures.TablesTest): fetched_pk = config.db.scalar(select([table.c.id])) eq_(fetched_pk, pk) + def test_explicit_returning_pk_no_autocommit(self): + engine = config.db + table = self.tables.autoinc_pk + with engine.begin() as conn: + r = conn.execute( + table.insert().returning( + table.c.id), + data="some data" + ) + pk = r.first()[0] + fetched_pk = config.db.scalar(select([table.c.id])) + eq_(fetched_pk, pk) + def test_autoincrement_on_insert_implcit_returning(self): config.db.execute( diff --git a/lib/sqlalchemy/testing/suite/test_reflection.py b/lib/sqlalchemy/testing/suite/test_reflection.py index 5a8a54c46..228bf44ce 100644 --- a/lib/sqlalchemy/testing/suite/test_reflection.py +++ b/lib/sqlalchemy/testing/suite/test_reflection.py @@ -180,6 +180,12 @@ class ComponentReflectionTest(fixtures.TablesTest): def test_get_view_names_with_schema(self): self._test_get_table_names('test_schema', table_type='view') + @testing.requires.table_reflection + @testing.requires.view_reflection + def test_get_tables_and_views(self): + self._test_get_table_names() + self._test_get_table_names(table_type='view') + def _test_get_columns(self, schema=None, table_type='table'): meta = MetaData(testing.db) users, addresses, dingalings = self.tables.users, \ diff --git a/test/dialect/test_firebird.py b/test/dialect/test_firebird.py index 4a71b7d05..222e34b93 100644 --- a/test/dialect/test_firebird.py +++ b/test/dialect/test_firebird.py @@ -352,6 +352,15 @@ class CompileTest(fixtures.TestBase, AssertsCompiledSQL): for type_, args, kw, res in columns: self.assert_compile(type_(*args, **kw), res) + def test_quoting_initial_chars(self): + self.assert_compile( + column("_somecol"), + '"_somecol"' + ) + self.assert_compile( + column("$somecol"), + '"$somecol"' + ) class TypesTest(fixtures.TestBase): __only_on__ = 'firebird' diff --git a/test/requirements.py b/test/requirements.py index b6fca06ed..b90591a80 100644 --- a/test/requirements.py +++ b/test/requirements.py @@ -123,6 +123,18 @@ class DefaultRequirements(SuiteRequirements): ) @property + def insert_from_select(self): + return skip_if( + ["firebird"], "crashes for unknown reason" + ) + + @property + def fetch_rows_post_commit(self): + return skip_if( + ["firebird"], "not supported" + ) + + @property def binary_comparisons(self): """target database/driver can allow BLOB/BINARY fields to be compared against a bound parameter value. @@ -503,10 +515,10 @@ class DefaultRequirements(SuiteRequirements): """target backend supports Decimal() objects using E notation to represent very large values.""" - return fails_if( - ("sybase+pyodbc", None, None, + return skip_if( + [("sybase+pyodbc", None, None, "Don't know how do get these values through FreeTDS + Sybase"), - ("firebird", None, None, "Precision must be from 1 to 18"), + ("firebird", None, None, "Precision must be from 1 to 18"),] ) @property @@ -545,11 +557,21 @@ class DefaultRequirements(SuiteRequirements): """target backend will return native floating point numbers with at least seven decimal places when using the generic Float type.""" - return fails_if('mysql', 'mysql FLOAT type only returns 4 decimals') + return fails_if([ + ('mysql', None, None, + 'mysql FLOAT type only returns 4 decimals'), + ('firebird', None, None, + "firebird FLOAT type isn't high precision"), + ]) @property def floats_to_four_decimals(self): - return fails_if("mysql+oursql", "Floating point error") + return fails_if([ + ("mysql+oursql", None, None, "Floating point error"), + ("firebird", None, None, + "Firebird still has FP inaccuracy even " + "with only four decimal places") + ]) @property def python2(self): |
