Skip to main content
Glama

update_column

Modify column values in CSV data using operations like replace, map, apply expressions, or fill missing values.

Instructions

Update values in a column using various operations with discriminated unions.

Returns: ColumnOperationResult with update details

Examples: # Using discriminated union - Replace operation update_column(ctx, "status", { "type": "replace", "pattern": "N/A", "replacement": "Unknown" })

# Using discriminated union - Map operation
update_column(ctx, "code", {
    "type": "map",
    "mapping": {"A": "Alpha", "B": "Beta"}
})

# Using discriminated union - Fill operation
update_column(ctx, "score", {
    "type": "fillna",
    "value": 0
})

# Legacy format still supported
update_column(ctx, "score", {
    "operation": "fillna",
    "value": 0
})

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
columnYesColumn name to update values in
operationYesUpdate operation specification (replace, map, apply, fillna)

Implementation Reference

  • Main handler function for the 'update_column' tool. Handles update operations (replace, map, apply, fillna) on a specified DataFrame column using discriminated unions or legacy dict formats. Updates the session DataFrame in-place and returns operation result.
    async def update_column(
        ctx: Annotated[Context, Field(description="FastMCP context for session access")],
        column: Annotated[str, Field(description="Column name to update values in")],
        operation: Annotated[
            UpdateOperationType | UpdateColumnRequest | dict[str, Any],
            Field(description="Update operation specification (replace, map, apply, fillna)"),
        ],
    ) -> ColumnOperationResult:
        """Update values in a column using various operations with discriminated unions.
    
        Returns:
            ColumnOperationResult with update details
    
        Examples:
            # Using discriminated union - Replace operation
            update_column(ctx, "status", {
                "type": "replace",
                "pattern": "N/A",
                "replacement": "Unknown"
            })
    
            # Using discriminated union - Map operation
            update_column(ctx, "code", {
                "type": "map",
                "mapping": {"A": "Alpha", "B": "Beta"}
            })
    
            # Using discriminated union - Fill operation
            update_column(ctx, "score", {
                "type": "fillna",
                "value": 0
            })
    
            # Legacy format still supported
            update_column(ctx, "score", {
                "operation": "fillna",
                "value": 0
            })
    
        """
        # Get session_id from FastMCP context
        session_id = ctx.session_id
        _session, df = get_session_data(session_id)
    
        if column not in df.columns:
            raise ColumnNotFoundError(column, df.columns.tolist())
    
        # Track initial state
        # Update column operation (no longer tracking null count changes)
        operation_type = "unknown"
    
        # Handle discriminated union operations
        if isinstance(
            operation,
            ReplaceOperation | MapOperation | ApplyOperation | FillNaOperation,
        ):
            if isinstance(operation, ReplaceOperation):
                operation_type = "replace"
                df[column] = df[column].replace(operation.pattern, operation.replacement)
            elif isinstance(operation, MapOperation):
                operation_type = "map"
                df[column] = df[column].map(operation.mapping)
            elif isinstance(operation, ApplyOperation):
                operation_type = "apply"
                expr = operation.expression
    
                # Use unified secure evaluator for both string and mathematical expressions
                result = _apply_expression_to_column(expr, column, df, "expression")
                df[column] = result
            elif isinstance(operation, FillNaOperation):
                operation_type = "fillna"
                df[column] = df[column].fillna(operation.value)
    
        # Handle legacy format or dict input
        elif isinstance(operation, dict):
            if "type" in operation:
                # Parse as discriminated union
                if operation["type"] == "replace":
                    replace_op = ReplaceOperation(**operation)
                    operation_type = "replace"
                    df[column] = df[column].replace(
                        replace_op.pattern,
                        replace_op.replacement,
                    )
                elif operation["type"] == "map":
                    map_op = MapOperation(**operation)
                    operation_type = "map"
                    df[column] = df[column].map(map_op.mapping)
                elif operation["type"] == "apply":
                    apply_op = ApplyOperation(**operation)
                    operation_type = "apply"
                    expr = apply_op.expression
    
                    # Use unified secure evaluator for both string and mathematical expressions
                    result = _apply_expression_to_column(expr, column, df, "expression")
                    df[column] = result
                elif operation["type"] == "fillna":
                    fillna_op = FillNaOperation(**operation)
                    operation_type = "fillna"
                    df[column] = df[column].fillna(fillna_op.value)
                else:
                    msg = "type"
                    raise InvalidParameterError(
                        msg,
                        operation["type"],
                        "Supported types: replace, map, apply, fillna",
                    )
            else:
                # Legacy format with "operation" field
                update_request = UpdateColumnRequest(**operation)
                operation_type = update_request.operation
    
                if update_request.operation == "replace":
                    if update_request.pattern is None or update_request.replacement is None:
                        msg = "pattern/replacement"
                        raise InvalidParameterError(
                            msg,
                            f"{update_request.pattern}/{update_request.replacement}",
                            "Both pattern and replacement required for replace operation",
                        )
                    df[column] = df[column].replace(
                        update_request.pattern,
                        update_request.replacement,
                    )
                elif update_request.operation == "map":
                    if not isinstance(update_request.value, dict):
                        msg = "value"
                        raise InvalidParameterError(
                            msg,
                            str(update_request.value),
                            "Dictionary mapping required for map operation",
                        )
                    df[column] = df[column].map(update_request.value)
                elif update_request.operation == "apply":
                    if update_request.value is None:
                        msg = "value"
                        raise InvalidParameterError(
                            msg,
                            str(update_request.value),
                            "Expression required for apply operation",
                        )
                    if isinstance(update_request.value, str):
                        expr = update_request.value
    
                        # Use unified secure evaluator for both string and mathematical expressions
                        result = _apply_expression_to_column(expr, column, df, "value")
                        df[column] = result
                    else:
                        df[column] = df[column].apply(update_request.value)
                elif update_request.operation == "fillna":
                    if update_request.value is None:
                        msg = "value"
                        raise InvalidParameterError(
                            msg,
                            str(update_request.value),
                            "Fill value required for fillna operation",
                        )
                    df[column] = df[column].fillna(update_request.value)
                else:
                    msg = "operation"
                    raise InvalidParameterError(
                        msg,
                        update_request.operation,
                        "Supported operations: replace, map, apply, fillna",
                    )
        else:
            # Handle legacy UpdateColumnRequest object
            update_request = operation
            operation_type = update_request.operation
            # ... (same logic as above legacy handling)
    
        # Operation completed
    
        # No longer recording operations (simplified MCP architecture)
    
        return ColumnOperationResult(
            operation=f"update_{operation_type}",
            rows_affected=len(df),
            columns_affected=[column],
        )
  • Pydantic model defining the input schema for legacy update_column requests, supporting replace, map, apply, fillna operations.
    class UpdateColumnRequest(BaseModel):
        """Request parameters for column update operations."""
    
        model_config = ConfigDict(extra="forbid")
        operation: Literal["replace", "map", "apply", "fillna"] = Field(
            description="Type of update operation",
        )
        value: Any | None = Field(  # Any justified: operation-dependent type (CellValue|dict|str)
            None,
            description="Value for the operation (depends on operation type)",
        )
        pattern: str | None = Field(None, description="Pattern for replace operation")
        replacement: str | None = Field(None, description="Replacement for replace operation")
  • Discriminated union type for modern update operations (ReplaceOperation, MapOperation, ApplyOperation, FillNaOperation), used in the tool handler.
    UpdateOperationType = Annotated[
        ReplaceOperation | MapOperation | ApplyOperation | FillNaOperation,
        Field(discriminator="type"),
    ]
  • Registration of the update_column handler as an MCP tool on the column_server FastMCP instance.
    column_server.tool(name="update_column")(update_column)
  • Helper function used in 'apply' operation to safely evaluate expressions on column values, referenced as 'x'.
    def _apply_expression_to_column(
        expression: str,
        column: str,
        dataframe: pd.DataFrame,
        error_context: str = "expression",
    ) -> pd.Series:
        """Apply a string or mathematical expression to a column safely.
    
        Args:
            expression: The expression to evaluate (e.g., "x.upper()", "x + 10")
            column: The column name to use as 'x' in the expression
            dataframe: The DataFrame containing the column
            error_context: Context for error messages (e.g., "expression", "value")
    
        Returns:
            pd.Series: Result of the expression evaluation
    
        Raises:
            InvalidParameterError: If the expression is invalid or evaluation fails
    
        """
        try:
            # Create column context mapping for 'x' variable
            column_context = {"x": column}
            # Use unified expression evaluator that handles both string and math operations
            return evaluate_string_expression_safely(expression, dataframe, column_context)
        except Exception as e:
            msg = error_context
            raise InvalidParameterError(
                msg,
                expression,
                f"Invalid expression. Use 'x' to reference column values. Error: {e}",
            ) from e

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jonpspri/databeak'

If you have feedback or need assistance with the MCP directory API, please join our Discord server