Esempio n. 1
0
    def save(self):
        """
        Creates / updates a row.
        This is a blind insert call.
        All validation and cleaning needs to happen
        prior to calling this.
        """
        if self.instance is None:
            raise CQLEngineException("DML Query intance attribute is None")
        assert type(self.instance) == self.model

        nulled_fields = set()
        if self.instance._has_counter or self.instance._can_update():
            return self.update()
        else:
            insert = InsertStatement(self.column_family_name, ttl=self._ttl, timestamp=self._timestamp, if_not_exists=self._if_not_exists)
            for name, col in self.instance._columns.items():
                val = getattr(self.instance, name, None)
                if col._val_is_null(val):
                    if self.instance._values[name].changed:
                        nulled_fields.add(col.db_field_name)
                    continue
                insert.add_assignment_clause(AssignmentClause(
                    col.db_field_name,
                    col.to_database(getattr(self.instance, name, None))
                ))

        # skip query execution if it's empty
        # caused by pointless update queries
        if not insert.is_empty:
            self._execute(insert)
        # delete any nulled columns
        self._delete_null_columns()
Esempio n. 2
0
    def save(self):
        """
        Creates / updates a row.
        This is a blind insert call.
        All validation and cleaning needs to happen
        prior to calling this.
        """
        if self.instance is None:
            raise CQLEngineException("DML Query intance attribute is None")
        assert type(self.instance) == self.model

        nulled_fields = set()
        if self.instance._has_counter or self.instance._can_update():
            return self.update()
        else:
            insert = InsertStatement(self.column_family_name, ttl=self._ttl, timestamp=self._timestamp)
            for name, col in self.instance._columns.items():
                val = getattr(self.instance, name, None)
                if col._val_is_null(val):
                    if self.instance._values[name].changed:
                        nulled_fields.add(col.db_field_name)
                    continue
                insert.add_assignment_clause(AssignmentClause(
                    col.db_field_name,
                    col.to_database(getattr(self.instance, name, None))
                ))

        # skip query execution if it's empty
        # caused by pointless update queries
        if not insert.is_empty:
            self._execute(insert)

        # delete any nulled columns
        self._delete_null_columns()
    def test_statement(self):
        ist = InsertStatement('table', None)
        ist.add_assignment_clause(AssignmentClause('a', 'b'))
        ist.add_assignment_clause(AssignmentClause('c', 'd'))

        self.assertEqual(
            unicode(ist),
            'INSERT INTO table ("a", "c") VALUES (%(0)s, %(1)s)'
        )
    def test_statement(self):
        ist = InsertStatement('table', None)
        ist.add_assignment_clause(AssignmentClause('a', 'b'))
        ist.add_assignment_clause(AssignmentClause('c', 'd'))

        self.assertEqual(
            six.text_type(ist),
            'INSERT INTO table ("a", "c") VALUES (%(0)s, %(1)s)'
        )
    def test_context_update(self):
        ist = InsertStatement('table', None)
        ist.add_assignment_clause(AssignmentClause('a', 'b'))
        ist.add_assignment_clause(AssignmentClause('c', 'd'))

        ist.update_context_id(4)
        self.assertEqual(
            six.text_type(ist),
            'INSERT INTO table ("a", "c") VALUES (%(4)s, %(5)s)'
        )
        ctx = ist.get_context()
        self.assertEqual(ctx, {'4': 'b', '5': 'd'})
    def test_context_update(self):
        ist = InsertStatement('table', None)
        ist.add_assignment_clause(AssignmentClause('a', 'b'))
        ist.add_assignment_clause(AssignmentClause('c', 'd'))

        ist.update_context_id(4)
        self.assertEqual(
            unicode(ist),
            'INSERT INTO table ("a", "c") VALUES (%(4)s, %(5)s)'
        )
        ctx = ist.get_context()
        self.assertEqual(ctx, {'4': 'b', '5': 'd'})
    def save(self, *objects):
        """Flush all pending changes to Cassandra.

        objects -- if not None, only operate on this or these object(s)

        """
        updates = set()
        counter_updates = set()
        creates = set()
        counter_creates = set()
        for model_class, by_key in self.instances_by_class.iteritems():
            for key, instance in by_key.iteritems():
                if hasattr(instance, '_created') and instance._created:
                    if model_class.id_mapped_class._has_counter:
                        counter_creates.add(instance)
                    else:
                        creates.add(instance)
                elif hasattr(instance, '_dirties'):
                    if model_class.id_mapped_class._has_counter:
                        counter_updates.add(instance)
                    else:
                        updates.add(instance)
        if objects:
            updates = updates and objects
            counter_updates = counter_updates and objects
            creates = creates and objects
            counter_creates = counter_creates and objects

        with BatchQuery() as batch:
            for create in creates:
                # Note we skip a lot of cqlengine code and create the
                # insert statement directly.
                # (this is the non-optimized code that is replaced below)
                #key_names = create.id_mapped_class._columns.keys()
                #arg = {name: getattr(create, name) for name in key_names}
                #create.id_mapped_class.batch(batch).create(**arg)
                # (end non-optimized code)
                # (begin optimized)
                # note: it might save time to memoize column family name
                # note: cqlengine-session doesn't yet support 'ttl'
                insert = InsertStatement(create.id_mapped_class.column_family_name())#, ttl=self._ttl)
                for name, col in create.id_mapped_class._columns.items():
                    val = col.validate(getattr(create, name))
                    if col._val_is_null(val):
                        continue
                    insert.add_assignment_clause(AssignmentClause(
                        col.db_field_name,
                        col.to_database(val)))
                # skip query execution if it's empty
                # caused by pointless update queries
                if not insert.is_empty:
                    batch.add_query(insert)
                # (end optimized)
                del create._created
                try:
                    del create._dirties
                except AttributeError:
                    pass
            for update in updates:
                key_names = update._primary_keys.keys()
                arg = {name: getattr(update, name) for name in key_names}
                dirties = update._dirties
                update.id_mapped_class.objects(**arg).batch(batch).update(**dirties)
                del update._dirties
        # It would seem that batch does not work with counter?
        #with BatchQuery() as batch:
        for create in counter_creates:
            primary_key_names = create.id_mapped_class._primary_keys.keys()
            arg = {name: getattr(create, name) for name in primary_key_names}
            instance = create.id_mapped_class.create(**arg)
            for name, col in create.id_mapped_class._columns.items():
                if isinstance(col, columns.Counter):
                    val = getattr(create, name)
                    setattr(instance, name, val)
            del create._created
            try:
                del create._dirties
            except AttributeError:
                pass
            instance.update()
        for update in counter_updates:
            statement = UpdateStatement(update.id_mapped_class.column_family_name())#, ttl=self._ttl)
            for name, value in update._dirties.items():
                col = update.id_mapped_class._columns[name]
                clause = CounterUpdateClause(col.db_field_name, value, 0, column=col)
                statement.add_assignment_clause(clause)
            for name, col in update.id_mapped_class._primary_keys.items():
                statement.add_where_clause(WhereClause(
                    col.db_field_name,
                    EqualsOperator(),
                    col.to_database(getattr(update, name))
                ))
            params = statement.get_context()
            statement = SimpleStatement(str(statement))
            cqlengine.connection.get_session().execute(statement, params)
            del update._dirties
#            for delete in self.deletes:
#                raise NotImplementedError
        for callable, args, kwargs in self.call_after_save:
            callable(*args, **kwargs)
        self.call_after_save = []
 def test_where_clause_failure(self):
     """ tests that where clauses cannot be added to Insert statements """
     ist = InsertStatement('table', None)
     with self.assertRaises(StatementException):
         ist.add_where_clause('s')
 def test_additional_rendering(self):
     ist = InsertStatement('table', ttl=60)
     ist.add_assignment_clause(AssignmentClause('a', 'b'))
     ist.add_assignment_clause(AssignmentClause('c', 'd'))
     self.assertIn('USING TTL 60', unicode(ist))
 def test_where_clause_failure(self):
     """ tests that where clauses cannot be added to Insert statements """
     ist = InsertStatement('table', None)
     with self.assertRaises(StatementException):
         ist.add_where_clause('s')
 def test_additional_rendering(self):
     ist = InsertStatement('table', ttl=60)
     ist.add_assignment_clause(AssignmentClause('a', 'b'))
     ist.add_assignment_clause(AssignmentClause('c', 'd'))
     self.assertIn('USING TTL 60', six.text_type(ist))