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 2e2adb3935)
(cherry picked from commit 2b20285a1a)
This commit is contained in:
Mike Fedosin 2015-12-16 17:05:45 +03:00 committed by Flavio Percoco
parent 42b551176a
commit 5cb8d33860
3 changed files with 31 additions and 11 deletions

View File

@ -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))

View File

@ -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,

View File

@ -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