From ef1472b3303ad22c3dc1aad2a7d63c229eb5d061 Mon Sep 17 00:00:00 2001 From: Adam Holmberg Date: Wed, 11 Feb 2015 11:46:26 -0600 Subject: [PATCH] Added some additional logging around connection setup and schema management. --- cassandra/cqlengine/connection.py | 15 +++++++++++++++ cassandra/cqlengine/exceptions.py | 1 + cassandra/cqlengine/management.py | 14 ++++++++++++-- cassandra/cqlengine/models.py | 1 - 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/cassandra/cqlengine/connection.py b/cassandra/cqlengine/connection.py index 6c5d4152..253598c2 100644 --- a/cassandra/cqlengine/connection.py +++ b/cassandra/cqlengine/connection.py @@ -45,10 +45,16 @@ def default(): (except for row_factory) """ global cluster, session + + if session: + log.warn("configuring new connection for cqlengine when one was already set") + cluster = Cluster() session = cluster.connect() session.row_factory = dict_factory + log.debug("cqlengine connection initialized with default session to localhost") + def set_session(s): """ @@ -58,11 +64,17 @@ def set_session(s): This may be relaxed in the future """ global cluster, session + + if session: + log.warn("configuring new connection for cqlengine when one was already set") + if s.row_factory is not dict_factory: raise CQLEngineException("Failed to initialize: 'Session.row_factory' must be 'dict_factory'.") session = s cluster = s.cluster + log.debug("cqlengine connection initialized with %s", s) + def setup( hosts, @@ -104,8 +116,10 @@ def setup( cluster = Cluster(hosts, **kwargs) try: session = cluster.connect() + log.debug("cqlengine connection initialized with internally created session") except NoHostAvailable: if retry_connect: + log.warn("connect failed, setting up for re-attempt on first use") kwargs['default_keyspace'] = default_keyspace kwargs['consistency'] = consistency kwargs['lazy_connect'] = False @@ -157,6 +171,7 @@ def get_cluster(): def handle_lazy_connect(): global lazy_connect_args if lazy_connect_args: + log.debug("lazy connect") hosts, kwargs = lazy_connect_args lazy_connect_args = None setup(hosts, **kwargs) diff --git a/cassandra/cqlengine/exceptions.py b/cassandra/cqlengine/exceptions.py index 09327687..6bc6e624 100644 --- a/cassandra/cqlengine/exceptions.py +++ b/cassandra/cqlengine/exceptions.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. + class CQLEngineException(Exception): pass diff --git a/cassandra/cqlengine/management.py b/cassandra/cqlengine/management.py index 7c7fcff4..958d252f 100644 --- a/cassandra/cqlengine/management.py +++ b/cassandra/cqlengine/management.py @@ -130,12 +130,14 @@ def _create_keyspace(name, durable_writes, strategy_class, strategy_options): else: log.info("Not creating keyspace %s because it already exists", name) + def delete_keyspace(name): msg = "Deprecated. Use drop_keyspace instead" warnings.warn(msg, DeprecationWarning) log.warn(msg) drop_keyspace(name) + def drop_keyspace(name): """ Drops a keyspace, if it exists. @@ -156,6 +158,8 @@ def sync_table(model): """ Inspects the model and creates / updates the corresponding table and columns. + This function can only add fields that are not part of the primary key. + 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. @@ -184,6 +188,7 @@ def sync_table(model): # check for an existing column family if raw_cf_name not in tables: + log.debug("sync_table creating new table %s", cf_name) qs = get_create_table(model) try: @@ -194,20 +199,26 @@ def sync_table(model): if "Cannot add already existing column family" not in unicode(ex): raise else: + log.debug("sync_table checking existing table %s", cf_name) # see if we're missing any columns fields = get_fields(model) field_names = [x.name for x in fields] + model_fields = set() for name, col in model._columns.items(): if col.primary_key or col.partition_key: continue # we can't mess with the PK + model_fields.add(name) if col.db_field_name in field_names: continue # skip columns already defined # add missing column using the column def query = "ALTER TABLE {} add {}".format(cf_name, col.get_column_def()) - log.debug(query) execute(query) + db_fields_not_in_model = model_fields.symmetric_difference(field_names) + if db_fields_not_in_model: + log.info("Table %s has fields not referenced by model: %s", cf_name, db_fields_not_in_model) + update_compaction(model) table = cluster.metadata.keyspaces[ks_name].tables[raw_cf_name] @@ -391,7 +402,6 @@ def update_compaction(model): options = json.dumps(options).replace('"', "'") cf_name = model.column_family_name() query = "ALTER TABLE {} with compaction = {}".format(cf_name, options) - log.debug(query) execute(query) return True diff --git a/cassandra/cqlengine/models.py b/cassandra/cqlengine/models.py index 85d432b8..980dffc5 100644 --- a/cassandra/cqlengine/models.py +++ b/cassandra/cqlengine/models.py @@ -42,7 +42,6 @@ class hybrid_classmethod(object): Allows a method to behave as both a class method and normal instance method depending on how it's called """ - def __init__(self, clsmethod, instmethod): self.clsmethod = clsmethod self.instmethod = instmethod