Repository: optuna/optuna

Issue:
GridSampler raises TypeError when used with PostgreSQL
### Expected behavior

The example from the documentation for [GridSampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.GridSampler.html#optuna.samplers.GridSampler) should work just the same when adding a PostgreSQL storage to optuna.create_study. Instead, it raises "TypeError: Object of type int64 is not JSON serializable"


### Environment

- Optuna version: 3.0.0
- Python version: 3.9.2
- OS: Linux-5.10.102.1-microsoft-standard-WSL2-x86_64-with-glibc2.28'
- (Optional) Other libraries and their versions:


### Error messages, stack traces, or logs

```shell
A new study created in RDB with name: no-name-2f43ea9c-821e-4731-9b57-741cc4bb831f
Traceback (most recent call last):
  File "/optuna_test.py", line 17, in <module>
    study.optimize(objective)
  File "/usr/local/lib/python3.9/site-packages/optuna/study/study.py", line 419, in optimize
    _optimize(
  File "/usr/local/lib/python3.9/site-packages/optuna/study/_optimize.py", line 66, in _optimize
    _optimize_sequential(
  File "/usr/local/lib/python3.9/site-packages/optuna/study/_optimize.py", line 160, in _optimize_sequential
    frozen_trial = _run_trial(study, func, catch)
  File "/usr/local/lib/python3.9/site-packages/optuna/study/_optimize.py", line 187, in _run_trial
    trial = study.ask()
  File "/usr/local/lib/python3.9/site-packages/optuna/study/study.py", line 514, in ask
    trial = trial_module.Trial(self, trial_id)
  File "/usr/local/lib/python3.9/site-packages/optuna/trial/_trial.py", line 54, in __init__
    self._init_relative_params()
  File "/usr/local/lib/python3.9/site-packages/optuna/trial/_trial.py", line 63, in _init_relative_params
    self.relative_params = self.study.sampler.sample_relative(
  File "/usr/local/lib/python3.9/site-packages/optuna/samplers/_grid.py", line 163, in sample_relative
    study._storage.set_trial_system_attr(trial._trial_id, "grid_id", grid_id)
  File "/usr/local/lib/python3.9/site-packages/optuna/storages/_cached_storage.py", line 318, in set_trial_system_attr
    self._backend.set_trial_system_attr(trial_id, key=key, value=value)
  File "/usr/local/lib/python3.9/site-packages/optuna/storages/_rdb/storage.py", line 782, in set_trial_system_attr
    self._set_trial_system_attr_without_commit(session, trial_id, key, value)
  File "/usr/local/lib/python3.9/site-packages/optuna/storages/_rdb/storage.py", line 794, in _set_trial_system_attr_without_commit
    trial_id=trial_id, key=key, value_json=json.dumps(value)
  File "/usr/local/lib/python3.9/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/local/lib/python3.9/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/local/lib/python3.9/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/local/lib/python3.9/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type int64 is not JSON serializable
```


### Steps to reproduce

1. Run the example from [GridSampler](https://optuna.readthedocs.io/en/stable/reference/samplers/generated/optuna.samplers.GridSampler.html#optuna.samplers.GridSampler) documentation, it works perfectly.
```python
import optuna

def objective(trial):
    x = trial.suggest_float("x", -100, 100)
    y = trial.suggest_int("y", -100, 100)
    return x**2 + y**2

search_space = {"x": [-50, 0, 50], "y": [-99, 0, 99]}
study = optuna.create_study(sampler=optuna.samplers.GridSampler(search_space))
study.optimize(objective)
```
2. Add a PostgreSQL storage, and it fails:
```python
import optuna

postgres_url = f"postgresql://{usr}:{pwd}@{host}:{port}/{name}?options=--search_path%3Doptuna"

def objective(trial):
    x = trial.suggest_float("x", -100, 100)
    y = trial.suggest_int("y", -100, 100)
    return x**2 + y**2

search_space = {"x": [-50, 0, 50], "y": [-99, 0, 99]}
study = optuna.create_study(sampler=optuna.samplers.GridSampler(search_space), storage=postgres_url)
study.optimize(objective)
```
3. Use PostgreSQL with TPE Sampler, and it works:
```python
import optuna

postgres_url = f"postgresql://{usr}:{pwd}@{host}:{port}/{name}?options=--search_path%3Doptuna"

def objective(trial):
    x = trial.suggest_float("x", -100, 100)
    y = trial.suggest_int("y", -100, 100)
    return x**2 + y**2

study = optuna.create_study(storage=postgres_url)
study.optimize(objective)
```



### Additional context (optional)

_No response_


Discussion:
Thank you for your bug report! I confirmed this bug also occur with SQLite.

```python
import optuna

sqlite_url = f"sqlite:///test.db"

def objective(trial):
    x = trial.suggest_float("x", -100, 100)
    y = trial.suggest_int("y", -100, 100)
    return x**2 + y**2

search_space = {"x": [-50, 0, 50], "y": [-99, 0, 99]}
study = optuna.create_study(sampler=optuna.samplers.GridSampler(search_space), storage=sqlite_url)
study.optimize(objective)
```

I think this line has a bug. `grid_id` should be `int` instead of `numpy.int64`.
https://github.com/optuna/optuna/blob/d21b1c0a1d74fb36f1c2c53b771333ac30d6f167/optuna/samplers/_grid.py#L160

Resolving patch:
diff --git a/optuna/samplers/_grid.py b/optuna/samplers/_grid.py
--- a/optuna/samplers/_grid.py
+++ b/optuna/samplers/_grid.py
@@ -157,7 +157,7 @@ def sample_relative(
 
         # In distributed optimization, multiple workers may simultaneously pick up the same grid.
         # To make the conflict less frequent, the grid is chosen randomly.
-        grid_id = self._rng.choice(target_grids)
+        grid_id = int(self._rng.choice(target_grids))
 
         study._storage.set_trial_system_attr(trial._trial_id, "search_space", self._search_space)
         study._storage.set_trial_system_attr(trial._trial_id, "grid_id", grid_id)


Test patch: