fix for "ValueError: 'column_name' is not in list" error on sync_table for models with primary keys only

https://github.com/cqlengine/cqlengine/issues/175
This commit is contained in:
Daniel Dotsenko
2014-04-09 10:49:04 -07:00
committed by Jon Haddad
parent 65f2ef9216
commit 2d22138c0d
2 changed files with 41 additions and 5 deletions

View File

@@ -65,6 +65,16 @@ def create_table(model, create_missing_keyspace=True):
sync_table(model, create_missing_keyspace)
def sync_table(model, create_missing_keyspace=True):
"""
Inspects the model and creates / updates the corresponding table and columns.
Note that the attributes removed from the model are not deleted on the database.
They become effectively ignored by (will not show up on) the model.
:param create_missing_keyspace: (Defaults to True) Flags to us that we need to create missing keyspace
mentioned in the model automatically.
:type create_missing_keyspace: bool
"""
if model.__abstract__:
raise CQLEngineException("cannot create table from abstract model")
@@ -238,12 +248,19 @@ def get_fields(model):
tmp = con.execute(query, {'ks_name': ks_name, 'col_family': col_family}, ONE)
column_indices = [tmp.columns.index('column_name'), tmp.columns.index('validator')]
# Tables containing only primary keys do not appear to create
# any entries in system.schema_columns, as only non-primary-key attributes
# appear to be inserted into the schema_columns table
if not tmp.results:
return []
column_name_positon = tmp.columns.index('column_name')
validator_positon = tmp.columns.index('validator')
try:
type_index = tmp.columns.index('type')
return [Field(x[column_indices[0]], x[column_indices[1]]) for x in tmp.results if x[type_index] == 'regular']
type_position = tmp.columns.index('type')
return [Field(x[column_name_positon], x[validator_positon]) for x in tmp.results if x[type_position] == 'regular']
except ValueError:
return [Field(x[column_indices[0]], x[column_indices[1]]) for x in tmp.results]
return [Field(x[column_name_positon], x[validator_positon]) for x in tmp.results]
# convert to Field named tuples

View File

@@ -2,7 +2,7 @@ from mock import MagicMock, patch
from cqlengine import ONE
from cqlengine.exceptions import CQLEngineException
from cqlengine.management import create_table, delete_table, get_fields
from cqlengine.management import create_table, delete_table, get_fields, sync_table
from cqlengine.tests.base import BaseCassEngTestCase
from cqlengine.connection import ConnectionPool, Host
from cqlengine import management
@@ -77,6 +77,11 @@ class CapitalizedKeyModel(Model):
secondKey = columns.Integer(primary_key=True)
someData = columns.Text()
class PrimaryKeysOnlyModel(Model):
first_ey = columns.Integer(primary_key=True)
second_key = columns.Integer(primary_key=True)
class CapitalizedKeyTest(BaseCassEngTestCase):
def test_table_definition(self):
@@ -142,3 +147,17 @@ class AddColumnTest(BaseCassEngTestCase):
self.assertEqual(len(fields), 4)
class SyncTableTests(BaseCassEngTestCase):
def setUp(self):
delete_table(PrimaryKeysOnlyModel)
def test_sync_table_works_with_primary_keys_only_tables(self):
sync_table(PrimaryKeysOnlyModel)
# primary-keys-only tables do not create entries in system.schema_columns
# table. Only non-primary keys are added to that table.
# Our code must deal with that eventuality properly (not crash)
# on subsequent runs of sync_table (which runs get_fields internally)
get_fields(PrimaryKeysOnlyModel)
sync_table(PrimaryKeysOnlyModel)