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. Change-Id: I52b3a0158db8e3dc48f19509d1f9f80420ee40ea Closes-bug: #1526804 Closes-bug: #1526675
This commit is contained in:
parent
4d5330088f
commit
2e2adb3935
@ -303,6 +303,10 @@ def _get_default_column_value(column_type):
|
||||
'integer': 0,
|
||||
'string': ''
|
||||
}
|
||||
|
||||
if isinstance(column_type, sa_sql.type_api.Variant):
|
||||
return _get_default_column_value(column_type.impl)
|
||||
|
||||
return type_schema[column_type.__visit_name__]
|
||||
|
||||
|
||||
|
@ -26,7 +26,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
|
||||
@ -44,11 +43,6 @@ from glance.common import timeutils
|
||||
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"""
|
||||
|
||||
@ -131,8 +125,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))
|
||||
|
@ -109,13 +109,15 @@ 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,
|
||||
comparator_factory=semver_db.VersionComparator)
|
||||
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,
|
||||
|
@ -42,6 +42,7 @@ from oslo_utils import uuidutils
|
||||
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
|
||||
@ -1887,6 +1888,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
|
||||
|
Loading…
x
Reference in New Issue
Block a user