Remove SQLite BigInteger/Integer translation logic

This patch removes code that was causing the
SQLAlchemy BigInteger type to render as INTEGER
on the SQLite backend only.  The comment
in create_shadow_table() in nova/db/sqlalchemy/utils.py
which states that BigInteger isn't supported by SQLite
is not correct.  SQLite has an "affinity"-based,
dynamic typing model [1] that allows virtually any
name to be used for a type; datatypes are actually
determined on a row-by-row basis, but any
type name that has the substring INT inside of it
is automatically given integer affinity by default,
so there is no limitation on this type.

There is one difference on SQLite between INTEGER
and BIGINT, and that is that SQLite's "rowid"
feature only takes effect for a primary key column
if it is named "INTEGER PRIMARY KEY" [2].  However,
as all tests pass here it does not seem to be the
case that we are using BigInteger primary keys
in tests, and if we were, I'd rather approach SQLite's
quirk here in a different way.

Note that this patch relies upon the assumption
that **SQLite is only used in Nova as a test database,
not in actual deployments**.  If this statement is
not true, then information on these other use cases
will be needed.

Due to Alembic issue #341 [3] which has been resolved
for version 0.8.4 [4], the comparison of
INTEGER/BIGINT/SMALLINT is now significant by default,
so this change (or alternatively, one that changes Nova's
type comparison rules within migration tests) is needed
in order for Nova to pass the test_migrations test; the
error condition that raises with the latest Alembic is
shown in [5].

[1] http://sqlite.org/datatype3.html

[2] http://sqlite.org/lang_createtable.html#rowid

[3] https://bitbucket.org/zzzeek/alembic/issues/341/integer-vs-biginteger-diffrence-are-not

[4] http://alembic.readthedocs.org/en/latest/changelog.html#change-f8a974100f54b74d7f90ef765edae1ed

[5] http://paste.openstack.org/show/480966/

Change-Id: I05469578a748a33fdf3c0aa5a5fee1bbe69b94cd
This commit is contained in:
Mike Bayer 2015-12-05 22:34:17 -05:00
parent 3f8c69b2ef
commit 793f4b7c71
2 changed files with 0 additions and 76 deletions

View File

@ -1,23 +0,0 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from sqlalchemy import BigInteger
from sqlalchemy.ext.compiler import compiles
@compiles(BigInteger, 'sqlite')
def compile_big_int_sqlite(type_, compiler, **kw):
return 'INTEGER'

View File

@ -1,53 +0,0 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# Copyright 2010 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Test cases for sqlite-specific logic"""
from sqlalchemy import create_engine
from sqlalchemy import Column, BigInteger, String
import sqlalchemy.engine.reflection
from sqlalchemy.ext.declarative import declarative_base
from nova import test
class TestSqlite(test.NoDBTestCase):
"""Tests for sqlite-specific logic."""
def test_big_int_mapping(self):
base_class = declarative_base()
class User(base_class):
"""Dummy class with a BigInteger column for testing."""
__tablename__ = "users"
id = Column(BigInteger, primary_key=True)
name = Column(String)
engine = create_engine('sqlite://')
base_class.metadata.create_all(engine)
insp = sqlalchemy.engine.reflection.Inspector.from_engine(engine)
id_type = None
for column in insp.get_columns('users'):
if column['name'] == 'id':
id_type = column['type'].compile()
# NOTE(russellb) We have a hook in nova.db.sqlalchemy that makes it so
# BigInteger() is compiled to INTEGER for sqlite instead of BIGINT.
self.assertEqual('INTEGER', id_type)