To solve this optimization problem, we first need to define the decision variables and the objective function. Let's denote the number of units of Piano A to be sold as `x` and the number of units of Piano B to be sold as `y`. The objective is to minimize the total cost incurred by TomMusic while attracting at least 250 customers into its store daily.

The costs associated with selling each unit of Piano A and Piano B are $12 and $4, respectively. However, we also need to account for the purchase cost of each piano, which is $20 for Piano A and $15 for Piano B. Thus, the total cost for purchasing and selling `x` units of Piano A and `y` units of Piano B would be `20x + 12x + 15y + 4y`, simplifying to `32x + 19y`.

Given that each unit of Piano A attracts 25 customers and each unit of Piano B attracts 10 customers, we want `25x + 10y >= 250` to ensure at least 250 customers are attracted daily.

The budget constraint is given by the purchase costs of the pianos, which should not exceed $450. Thus, `20x + 15y <= 450`.

We also know that `x` and `y` must be non-negative since we cannot sell a negative number of pianos.

Now, let's formulate this problem in Gurobi code:

```python
from gurobipy import *

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

# Define the decision variables
x = m.addVar(vtype=GRB.INTEGER, name="Piano_A")
y = m.addVar(vtype=GRB.INTEGER, name="Piano_B")

# Define the objective function: minimize total cost
m.setObjective(32*x + 19*y, GRB.MINIMIZE)

# Add constraints
m.addConstr(25*x + 10*y >= 250, "Attract_at_least_250_customers")
m.addConstr(20*x + 15*y <= 450, "Daily_budget_constraint")

# Optimize the model
m.optimize()

# Print the solution
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Piano A units: {x.x}")
    print(f"Piano B units: {y.x}")
    print(f"Total cost: {m.objVal}")
else:
    print("No optimal solution found")
```