def saveMany(clasz, namespace, *models): '''Write a Lot of Models in one batch, They must all belong to one keyspace''' from homer.core.models import key, BaseModel # PERSISTS ALL CHANGES IN *MODELS IN A SINGLE BATCH def commit(namespace, mutations): '''Stores all the mutations in one batch operation''' pool = poolFor(namespace) with using(pool) as conn: keyspace = keyspaceFor(namespace) conn.client.set_keyspace(keyspace) conn.client.batch_mutate(mutations, clasz.consistency) # BATCH ALL THE INDIVIDUAL CHANGES IN ONE TRANSFER mutations = {} for model in models: assert issubclass(model.__class__, BaseModel), "parameter model:\ %s must inherit from BaseModel" % model info = Schema.Get(model) keyspace = keyspaceFor(info[0]) mnamespace = info[0] assert namespace == mnamespace, "All the Models must belong to %s for this operation to complete" % namespace kind = info[1] if kind not in __COLUMNFAMILIES__ and Settings.debug(): Lisa.create(model) meta = MetaModel(model) key = model.key() key.saved = True mutations[meta.id()] = meta.mutations() commit(namespace,mutations)
def makeColumnFamily(self, connection): '''Creates a new column family from the 'kind' property of this BaseModel''' try: connection.client.set_keyspace(self.keyspace) connection.client.system_add_column_family(self.asColumnFamily()) self.wait(connection) except InvalidRequestException as e: if Settings.debug(): print_exc()
def MakeModels(self, *models): '''Tries to bootstrap all the models that have been passed in''' from homer.core.models import Model for model in models: try: logging.info("Creating Model: %s" % model) Lisa.create(model); except: if Settings.debug(): print_exc()
def MakeEveryModel(self): '''Tries to create all the models, registered on Homer''' from homer.core.models import Schema namespaces = Schema.schema.keys() for namespace in namespaces: kinds = Schema.schema[namespace].keys() for kind in kinds: try: logging.info("Creating Model: %s, %s" % (namespace, kind)) clasz = Schema.ClassForModel(namespace, kind) instance = clasz() Lisa.create(instance); except: if Settings.debug(): print_exc()
def __iter__(self): '''Execute your queries and converts data to python data models''' # EXECUTE THE QUERY IF IT HASN'T BEEN EXECUTED try: if self.cursor is None: self.execute() except Exception as e: logging.exception("Something wen't wrong when executing the query: %s, error: %s" % self, str(e)) if Settings.debug(): print_exc() # FOR SOME ODD REASON CASSANDRA 1.0.0 ALWAYS RETURNS CqlResultType.ROWS, # SO TO FIGURE OUT COUNTS I MANUALLY SEARCH THE QUERY WITH A REGEX if re.search(self.pattern, self.query): logging.info("Count expression found;") yield self.cursor.fetchone()[0] else: logging.info("Deciphering rows as usual") cursor = self.cursor description = self.cursor.description if not description: raise StopIteration names = [tuple[0] for tuple in description] row = cursor.fetchone() while row: model = self.kind() descs = fields(model, Property) values = {} for name, value in zip(names, row): if not value: continue if name == "KEY": continue #Ignore the KEY attribute prop = descs.get(name, None) if prop: found = prop.deconvert(value) model[name] = found else: k, v = model.default k = k() if isinstance(k, type) else k v = v() if isinstance(v, type) else v name = k.deconvert(value) value = v.deconvert(value) model[name] = value yield model row = cursor.fetchone()
def makeIndexes(self, connection): '''Creates Indices for all the indexed properties in the model''' query = 'CREATE INDEX ON {kind}({name});' for name, property in self.fields.items(): if property.saveable() and property.indexed(): try: logging.info("Creating index on: %s" % property) cursor = connection.cursor() formatted = query.format(kind = self.kind, name= property.name) cursor.execute("USE %s;" % self.keyspace) cursor.execute(formatted) except Exception as e: logging.exception(e) if Settings.debug(): print_exc() else: logging.info("%s is not indexable" % property) self.wait(connection)
def save(clasz, model): '''Write one Model to Cassandra''' from homer.core.models import key, BaseModel # PUT PERSISTS ALL CHANGES IN A MODEL IN A SINGLE BATCH def commit(namespace, mutations): '''Stores all the mutations in one batch operation''' pool = poolFor(namespace) with using(pool) as conn: keyspace = keyspaceFor(namespace) conn.client.set_keyspace(keyspace) conn.client.batch_mutate(mutations, clasz.consistency) assert issubclass(model.__class__, BaseModel), "%s must inherit from BaseModel" % model info = Schema.Get(model) namespace = info[0] kind = info[1] if kind not in __COLUMNFAMILIES__ and Settings.debug(): Lisa.create(model) meta = MetaModel(model) changes = { meta.id() : meta.mutations() } commit(namespace, changes) key = model.key() key.saved = True
def execute(self): '''Executes @self.query in self.keyspace and returns a cursor''' # FIGURE OUT WHICH KEYSPACE THE MODEL BELONGS TO if not self.keyspace: self.namespace = Schema.Get(self.kind)[0] #Every Model is guaranteed to have a namespace at init time. self.keyspace = keyspaceFor(self.namespace) logging.info("Executing Query: %s in %s" % (self.query, self.keyspace)) if not self.kind.__name__ in __COLUMNFAMILIES__ and Settings.debug(): logging.info("Creating new Column Family: %s " % self.kind.__name__) Lisa.create(self.kind()) pool = poolFor(self.namespace) with using(pool) as conn: logging.info("Executing %s" % self) conn.client.set_keyspace(self.keyspace) cursor = conn.cursor() keywords = self.keywords if self.convert: logging.info("Converting parameters for query: %s" % self.query) keywords = self.parse(keywords) cursor.execute(self.query, dict(keywords)) self.cursor = cursor