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:
committed by
Jon Haddad
parent
65f2ef9216
commit
2d22138c0d
@@ -65,6 +65,16 @@ def create_table(model, create_missing_keyspace=True):
|
|||||||
sync_table(model, create_missing_keyspace)
|
sync_table(model, create_missing_keyspace)
|
||||||
|
|
||||||
def sync_table(model, create_missing_keyspace=True):
|
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__:
|
if model.__abstract__:
|
||||||
raise CQLEngineException("cannot create table from abstract model")
|
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)
|
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:
|
try:
|
||||||
type_index = tmp.columns.index('type')
|
type_position = tmp.columns.index('type')
|
||||||
return [Field(x[column_indices[0]], x[column_indices[1]]) for x in tmp.results if x[type_index] == 'regular']
|
return [Field(x[column_name_positon], x[validator_positon]) for x in tmp.results if x[type_position] == 'regular']
|
||||||
except ValueError:
|
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
|
# convert to Field named tuples
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from mock import MagicMock, patch
|
|||||||
|
|
||||||
from cqlengine import ONE
|
from cqlengine import ONE
|
||||||
from cqlengine.exceptions import CQLEngineException
|
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.tests.base import BaseCassEngTestCase
|
||||||
from cqlengine.connection import ConnectionPool, Host
|
from cqlengine.connection import ConnectionPool, Host
|
||||||
from cqlengine import management
|
from cqlengine import management
|
||||||
@@ -77,6 +77,11 @@ class CapitalizedKeyModel(Model):
|
|||||||
secondKey = columns.Integer(primary_key=True)
|
secondKey = columns.Integer(primary_key=True)
|
||||||
someData = columns.Text()
|
someData = columns.Text()
|
||||||
|
|
||||||
|
class PrimaryKeysOnlyModel(Model):
|
||||||
|
first_ey = columns.Integer(primary_key=True)
|
||||||
|
second_key = columns.Integer(primary_key=True)
|
||||||
|
|
||||||
|
|
||||||
class CapitalizedKeyTest(BaseCassEngTestCase):
|
class CapitalizedKeyTest(BaseCassEngTestCase):
|
||||||
|
|
||||||
def test_table_definition(self):
|
def test_table_definition(self):
|
||||||
@@ -142,3 +147,17 @@ class AddColumnTest(BaseCassEngTestCase):
|
|||||||
self.assertEqual(len(fields), 4)
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user