From 5cb8d33860fbadcaee7dbcf61b866c5ce18b5054 Mon Sep 17 00:00:00 2001 From: Mike Fedosin Date: Wed, 16 Dec 2015 17:05:45 +0300 Subject: [PATCH] Fix model sync for SQLite This code fixes the situation when several models are mismatched for SQLite because of type inconsistencies between Integer and BigInteger in sqlalchemy. Conflicts: glance/db/sqlalchemy/models_artifacts.py Change-Id: I52b3a0158db8e3dc48f19509d1f9f80420ee40ea Closes-bug: #1526804 Closes-bug: #1526675 (cherry picked from commit 2e2adb3935bcbf9dc6e100c4ba9a8e1b4bf3a4e6) (cherry picked from commit 2b20285a1a48aa88e6d101e62d4bef2b9eda1c35) --- glance/db/sqlalchemy/models.py | 10 ++-------- glance/db/sqlalchemy/models_artifacts.py | 9 ++++++--- glance/tests/unit/test_migrations.py | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/glance/db/sqlalchemy/models.py b/glance/db/sqlalchemy/models.py index ee1d64d18d..7ea831c025 100644 --- a/glance/db/sqlalchemy/models.py +++ b/glance/db/sqlalchemy/models.py @@ -27,7 +27,6 @@ from sqlalchemy import BigInteger from sqlalchemy import Boolean from sqlalchemy import Column from sqlalchemy import DateTime -from sqlalchemy.ext.compiler import compiles from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import ForeignKey from sqlalchemy import Index @@ -43,11 +42,6 @@ from sqlalchemy import UniqueConstraint BASE = declarative_base() -@compiles(BigInteger, 'sqlite') -def compile_big_int_sqlite(type_, compiler, **kw): - return 'INTEGER' - - class JSONEncodedDict(TypeDecorator): """Represents an immutable structure as a json-encoded string""" @@ -128,8 +122,8 @@ class Image(BASE, GlanceBase): name = Column(String(255)) disk_format = Column(String(20)) container_format = Column(String(20)) - size = Column(BigInteger) - virtual_size = Column(BigInteger) + size = Column(BigInteger().with_variant(Integer, "sqlite")) + virtual_size = Column(BigInteger().with_variant(Integer, "sqlite")) status = Column(String(30), nullable=False) is_public = Column(Boolean, nullable=False, default=False) checksum = Column(String(32)) diff --git a/glance/db/sqlalchemy/models_artifacts.py b/glance/db/sqlalchemy/models_artifacts.py index 4f542cf457..5c2297a417 100644 --- a/glance/db/sqlalchemy/models_artifacts.py +++ b/glance/db/sqlalchemy/models_artifacts.py @@ -111,12 +111,14 @@ class Artifact(BASE, ArtifactBase): default=lambda: str(uuid.uuid4())) name = Column(String(255), nullable=False) type_name = Column(String(255), nullable=False) - type_version_prefix = Column(BigInteger, nullable=False) + type_version_prefix = Column(BigInteger().with_variant(Integer, "sqlite"), + nullable=False) type_version_suffix = Column(String(255)) type_version_meta = Column(String(255)) type_version = composite(semver_db.DBVersion, type_version_prefix, type_version_suffix, type_version_meta) - version_prefix = Column(BigInteger, nullable=False) + version_prefix = Column(BigInteger().with_variant(Integer, "sqlite"), + nullable=False) version_suffix = Column(String(255)) version_meta = Column(String(255)) version = composite(semver_db.DBVersion, version_prefix, @@ -294,7 +296,8 @@ class ArtifactBlob(BASE, ArtifactBase): nullable=False) name = Column(String(255), nullable=False) item_key = Column(String(329)) - size = Column(BigInteger(), nullable=False) + size = Column(BigInteger().with_variant(Integer, "sqlite"), + nullable=False) checksum = Column(String(32)) position = Column(Integer) artifact = relationship(Artifact, diff --git a/glance/tests/unit/test_migrations.py b/glance/tests/unit/test_migrations.py index 69418c433e..ec1fd4feec 100644 --- a/glance/tests/unit/test_migrations.py +++ b/glance/tests/unit/test_migrations.py @@ -43,6 +43,7 @@ from oslo_utils import timeutils from six.moves import range import sqlalchemy from sqlalchemy import inspect +import sqlalchemy.types as types from glance.common import crypt from glance.common import exception @@ -1685,6 +1686,28 @@ class ModelsMigrationSyncMixin(object): def db_sync(self, engine): migration.db_sync(engine=engine) + # TODO(akamyshikova): remove this method as soon as comparison with Variant + # will be implemented in oslo.db or alembic + def compare_type(self, ctxt, insp_col, meta_col, insp_type, meta_type): + if isinstance(meta_type, types.Variant): + meta_orig_type = meta_col.type + insp_orig_type = insp_col.type + meta_col.type = meta_type.impl + insp_col.type = meta_type.impl + + try: + return self.compare_type(ctxt, insp_col, meta_col, insp_type, + meta_type.impl) + finally: + meta_col.type = meta_orig_type + insp_col.type = insp_orig_type + else: + ret = super(ModelsMigrationSyncMixin, self).compare_type( + ctxt, insp_col, meta_col, insp_type, meta_type) + if ret is not None: + return ret + return ctxt.impl.compare_type(insp_col, meta_col) + def include_object(self, object_, name, type_, reflected, compare_to): if name in ['migrate_version'] and type_ == 'table': return False