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