Metadef schema column name is a reserved word in MySQL

The metadef_properties and metadef_objects tables both have
a column named schema. Unfortunately, schema is a reserved word
in some relational database products, including MySQL and PostgreSQL.
The metadef_properties.schema and metadef_objects.schema
columns should be renamed to a non reserved word.

Change-Id: I9c1b497d2b09b9282a83bd8c19c32edfa4dd159f
Closes-Bug: 1378968
This commit is contained in:
Wayne Okuma 2014-10-08 08:17:20 -07:00
parent 27c179fe9f
commit 6a89a53c8f
9 changed files with 152 additions and 36 deletions

View File

@ -507,7 +507,7 @@ class MetadefObjectRepo(object):
# Convert the persisted json schema to a dict of PropertyTypes
property_types = {}
json_props = metadata_object['schema']
json_props = metadata_object['json_schema']
for id in json_props:
property_types[id] = fromjson(PropertyType, json_props[id])
@ -539,7 +539,7 @@ class MetadefObjectRepo(object):
'name': metadata_object.name,
'required': required_str,
'description': metadata_object.description,
'schema': db_schema
'json_schema': db_schema
}
return db_metadata_object
@ -694,14 +694,14 @@ class MetadefPropertyRepo(object):
namespace=namespace_entity,
property_id=property['id'],
name=property['name'],
schema=property['schema']
schema=property['json_schema']
)
def _format_metadef_property_to_db(self, property):
db_metadata_object = {
'name': property.name,
'schema': property.schema
'json_schema': property.schema
}
return db_metadata_object

View File

@ -1101,10 +1101,10 @@ def metadef_namespace_get_by_id(context, namespace_id):
namespace = next(namespace for namespace in DATA['metadef_namespaces']
if namespace['id'] == namespace_id)
except StopIteration:
msg = "No namespace found with id %s" % namespace_id
LOG.debug(msg)
raise exception.MetadefRecordNotFound(
record_type='namespace', id=namespace_id)
msg = (_("Metadata definition namespace not found for id=%s")
% namespace_id)
LOG.warn(msg)
raise exception.MetadefNamespaceNotFound(msg)
if not _is_namespace_visible(context, namespace):
msg = ("Forbidding request, metadata definition namespace=%s"
@ -1235,11 +1235,10 @@ def metadef_object_get_by_id(context, namespace_name, object_id):
object['id'] == object_id):
return object
else:
msg = ("No metadata definition object found with id %s"
msg = (_("Metadata definition object not found for id=%s")
% object_id)
LOG.debug(msg)
raise exception.MetadefRecordNotFound(record_type='object',
id=object_id)
LOG.warn(msg)
raise exception.MetadefObjectNotFound(msg)
@log_call
@ -1266,7 +1265,7 @@ def metadef_object_create(context, namespace_name, values):
object_values = copy.deepcopy(values)
object_name = object_values['name']
required_attributes = ['name']
allowed_attributes = ['name', 'description', 'schema', 'required']
allowed_attributes = ['name', 'description', 'json_schema', 'required']
namespace = metadef_namespace_get(context, namespace_name)
@ -1384,7 +1383,7 @@ def metadef_property_create(context, namespace_name, values):
property_values = copy.deepcopy(values)
property_name = property_values['name']
required_attributes = ['name']
allowed_attributes = ['name', 'description', 'schema', 'required']
allowed_attributes = ['name', 'description', 'json_schema', 'required']
namespace = metadef_namespace_get(context, namespace_name)
@ -1485,11 +1484,10 @@ def metadef_property_get_by_id(context, namespace_name, property_id):
property['id'] == property_id):
return property
else:
msg = ("No metadata definition property found with id=%s"
msg = (_("Metadata definition property not found for id=%s")
% property_id)
LOG.debug(msg)
raise exception.MetadefRecordNotFound(record_type='property',
id=property_id)
LOG.warn(msg)
raise exception.MetadefPropertyNotFound(msg)
@log_call
@ -1692,7 +1690,7 @@ def _format_property(values):
'id': _get_metadef_id(),
'namespace_id': None,
'name': None,
'schema': None
'json_schema': None
}
property.update(values)
return property
@ -1722,7 +1720,7 @@ def _format_object(values):
'namespace_id': None,
'name': None,
'description': None,
'schema': None,
'json_schema': None,
'required': None,
'created_at': dt,
'updated_at': dt

View File

@ -200,7 +200,7 @@ def _populate_metadata(meta, metadata_path=None):
values = {
'name': property,
'namespace_id': namespace_id,
'schema': json.dumps(schema),
'json_schema': json.dumps(schema),
'created_at': timeutils.utcnow()
}
_insert_data_to_db(metadef_properties_table, values)
@ -210,7 +210,7 @@ def _populate_metadata(meta, metadata_path=None):
'name': object.get('name', None),
'description': object.get('description', None),
'namespace_id': namespace_id,
'schema': json.dumps(object.get('properties', None)),
'json_schema': json.dumps(object.get('properties', None)),
'created_at': timeutils.utcnow()
}
_insert_data_to_db(metadef_objects_table, values)
@ -287,7 +287,7 @@ def _export_data_to_file(meta, path):
objects.append({
"name": object['name'],
"description": object['description'],
"properties": json.loads(object['schema'])
"properties": json.loads(object['json_schema'])
})
values.update({
'objects': objects
@ -296,7 +296,7 @@ def _export_data_to_file(meta, path):
properties = {}
for property in db_properties:
properties.update({
property['name']: json.loads(property['schema'])
property['name']: json.loads(property['json_schema'])
})
values.update({
'properties': properties

View File

@ -0,0 +1,34 @@
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
#
# 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.schema import MetaData
from sqlalchemy.schema import Table
def upgrade(migrate_engine):
meta = MetaData(bind=migrate_engine)
metadef_objects = Table('metadef_objects', meta, autoload=True)
metadef_objects.c.schema.alter(name='json_schema')
metadef_properties = Table('metadef_properties', meta, autoload=True)
metadef_properties.c.schema.alter(name='json_schema')
def downgrade(migrate_engine):
meta = MetaData(bind=migrate_engine)
metadef_objects = Table('metadef_objects', meta, autoload=True)
metadef_objects.c.json_schema.alter(name='schema')
metadef_properties = Table('metadef_properties', meta, autoload=True)
metadef_properties.c.json_schema.alter(name='schema')

View File

@ -89,7 +89,7 @@ class MetadefObject(BASE_DICT, GlanceMetadefBase):
name = Column(String(80), nullable=False)
description = Column(Text())
required = Column(Text())
schema = Column(JSONEncodedDict(), default={})
json_schema = Column(JSONEncodedDict(), default={})
class MetadefProperty(BASE_DICT, GlanceMetadefBase):
@ -103,7 +103,7 @@ class MetadefProperty(BASE_DICT, GlanceMetadefBase):
namespace_id = Column(Integer(), ForeignKey('metadef_namespaces.id'),
nullable=False)
name = Column(String(80), nullable=False)
schema = Column(JSONEncodedDict(), default={})
json_schema = Column(JSONEncodedDict(), default={})
class MetadefNamespaceResourceType(BASE_DICT, GlanceMetadefBase):

View File

@ -60,7 +60,7 @@ def build_object_fixture(**kwargs):
'name': u'test-object-name',
'description': u'test-object-description',
'required': u'fake-required-properties-list',
'schema': u'{fake-schema}'
'json_schema': u'{fake-schema}'
}
object.update(kwargs)
return object
@ -71,7 +71,7 @@ def build_property_fixture(**kwargs):
property = {
'namespace_id': 1,
'name': u'test-property-name',
'schema': u'{fake-schema}'
'json_schema': u'{fake-schema}'
}
property.update(kwargs)
return property
@ -244,7 +244,7 @@ class MetadefPropertyTests(object):
self.assertEqual(len(found), 2)
def test_property_update(self):
delta = {'name': u'New-name', 'schema': u'new-schema'}
delta = {'name': u'New-name', 'json_schema': u'new-schema'}
fixture_ns = build_namespace_fixture()
created_ns = self.db_api.metadef_namespace_create(
@ -263,7 +263,7 @@ class MetadefPropertyTests(object):
self.context, created_ns['namespace'],
created_prop['id'], delta_dict)
self.assertEqual(delta['name'], updated['name'])
self.assertEqual(delta['schema'], updated['schema'])
self.assertEqual(delta['json_schema'], updated['json_schema'])
def test_property_delete(self):
fixture_ns = build_namespace_fixture()
@ -354,7 +354,7 @@ class MetadefObjectTests(object):
self.assertEqual(len(found), 2)
def test_object_update(self):
delta = {'name': u'New-name', 'schema': u'new-schema',
delta = {'name': u'New-name', 'json_schema': u'new-schema',
'required': u'new-required'}
fixture_ns = build_namespace_fixture()
@ -374,7 +374,7 @@ class MetadefObjectTests(object):
self.context, created_ns['namespace'],
created_object['id'], delta_dict)
self.assertEqual(delta['name'], updated['name'])
self.assertEqual(delta['schema'], updated['schema'])
self.assertEqual(delta['json_schema'], updated['json_schema'])
def test_object_delete(self):
fixture_ns = build_namespace_fixture()

View File

@ -62,7 +62,7 @@ def _db_namespace_fixture(**kwargs):
def _db_property_fixture(name, **kwargs):
property = {
'name': name,
'schema': {"type": "string", "title": "title"},
'json_schema': {"type": "string", "title": "title"},
}
property.update(kwargs)
return property
@ -72,7 +72,7 @@ def _db_object_fixture(name, **kwargs):
obj = {
'name': name,
'description': None,
'schema': {},
'json_schema': {},
'required': '[]',
}
obj.update(kwargs)

View File

@ -1132,6 +1132,90 @@ class MigrationsMixin(test_migrations.WalkVersionsMixin):
db_utils.get_table, engine,
'metadef_namespace_resource_types')
def _pre_upgrade_036(self, engine):
meta = sqlalchemy.MetaData()
meta.bind = engine
# metadef_objects
table = sqlalchemy.Table("metadef_objects", meta, autoload=True)
expected_cols = [u'id',
u'namespace_id',
u'name',
u'description',
u'required',
u'schema',
u'created_at',
u'updated_at']
col_data = [col.name for col in table.columns]
self.assertEqual(expected_cols, col_data)
# metadef_properties
table = sqlalchemy.Table("metadef_properties", meta, autoload=True)
expected_cols = [u'id',
u'namespace_id',
u'name',
u'schema',
u'created_at',
u'updated_at']
col_data = [col.name for col in table.columns]
self.assertEqual(expected_cols, col_data)
def _check_036(self, engine, data):
meta = sqlalchemy.MetaData()
meta.bind = engine
# metadef_objects
table = sqlalchemy.Table("metadef_objects", meta, autoload=True)
expected_cols = [u'id',
u'namespace_id',
u'name',
u'description',
u'required',
u'json_schema',
u'created_at',
u'updated_at']
col_data = [col.name for col in table.columns]
self.assertEqual(expected_cols, col_data)
# metadef_properties
table = sqlalchemy.Table("metadef_properties", meta, autoload=True)
expected_cols = [u'id',
u'namespace_id',
u'name',
u'json_schema',
u'created_at',
u'updated_at']
col_data = [col.name for col in table.columns]
self.assertEqual(expected_cols, col_data)
def _post_downgrade_036(self, engine):
meta = sqlalchemy.MetaData()
meta.bind = engine
# metadef_objects
table = sqlalchemy.Table("metadef_objects", meta, autoload=True)
expected_cols = [u'id',
u'namespace_id',
u'name',
u'description',
u'required',
u'schema',
u'created_at',
u'updated_at']
col_data = [col.name for col in table.columns]
self.assertEqual(expected_cols, col_data)
# metadef_properties
table = sqlalchemy.Table("metadef_properties", meta, autoload=True)
expected_cols = [u'id',
u'namespace_id',
u'name',
u'schema',
u'created_at',
u'updated_at']
col_data = [col.name for col in table.columns]
self.assertEqual(expected_cols, col_data)
class TestMysqlMigrations(test_base.MySQLOpportunisticTestCase,
MigrationsMixin):

View File

@ -73,7 +73,7 @@ def _db_namespace_fixture(namespace, **kwargs):
def _db_property_fixture(name, **kwargs):
obj = {
'name': name,
'schema': {"type": "string", "title": "title"},
'json_schema': {"type": "string", "title": "title"},
}
obj.update(kwargs)
return obj
@ -83,7 +83,7 @@ def _db_object_fixture(name, **kwargs):
obj = {
'name': name,
'description': None,
'schema': {},
'json_schema': {},
'required': '[]',
}
obj.update(kwargs)