To solve the optimization problem described, we first need to translate the natural language description into a symbolic representation. This involves defining the variables, the objective function, and the constraints using algebraic terms.

Given:
- Variables: `milkshakes` and `sashimi`
- Objective Function: Maximize `7 * milkshakes + 1 * sashimi`
- Constraints:
  1. Calcium from milkshakes and sashimi must be at least 31 milligrams.
  2. `-6 * milkshakes + 7 * sashimi >= 0`
  3. Total calcium from milkshakes and sashimi must not exceed 52 milligrams.
  4. Both `milkshakes` and `sashimi` must be whole numbers.

Let's assign symbolic variables:
- `x1` for `milkshakes`
- `x2` for `sashimi`

The objective function in symbolic form is: `7*x1 + 1*x2`

Constraints in symbolic form:
1. `2*x1 + 12*x2 >= 31` (calcium constraint)
2. `-6*x1 + 7*x2 >= 0`
3. `2*x1 + 12*x2 <= 52` (total calcium limit)
4. `x1` and `x2` are integers.

Symbolic representation:
```json
{
  'sym_variables': [('x1', 'milkshakes'), ('x2', 'sashimi')],
  'objective_function': '7*x1 + 1*x2',
  'constraints': [
    '2*x1 + 12*x2 >= 31',
    '-6*x1 + 7*x2 >= 0',
    '2*x1 + 12*x2 <= 52',
    'x1 is an integer',
    'x2 is an integer'
  ]
}
```

Now, let's write the Gurobi code to solve this optimization problem:

```python
from gurobipy import *

# Create a new model
m = Model("Optimization_Problem")

# Add variables
x1 = m.addVar(vtype=GRB.INTEGER, name="milkshakes")
x2 = m.addVar(vtype=GRB.INTEGER, name="sashimi")

# Set the objective function
m.setObjective(7*x1 + 1*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(2*x1 + 12*x2 >= 31, "calcium_minimum")
m.addConstr(-6*x1 + 7*x2 >= 0, "sashimi_milkshake_ratio")
m.addConstr(2*x1 + 12*x2 <= 52, "total_calcium_limit")

# Optimize the model
m.optimize()

# Print the solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Milkshakes: {x1.x}")
    print(f"Sashimi: {x2.x}")
else:
    print("No optimal solution found")
```