prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  `TPESampler._sample_categorical` fails with PostgreSQL backend
  `TPESampler._sample_categorical` fails with PostgreSQL backend. This happens because:
  - `TPESampler._sample_categorical` returns an integer as `numpy.int32`.
  - The integer value is input to storage class without any cast.
  - SQLAlchemy with psycopg2 backend does not support `numpy.int32` input but does `int` one.
  
  **Repro Steps**
  With any objective function using categorical sampling (e.g., example one in `chainer_mnist.py`), invoke `minimize` as:
  ```
  study = pfnopt.create_study(storage=SOME_POSTGRES_URL)
  pfnopt.minimize(objective, n_trials=100, study=study)
  ```
  
  It fails after running trials `n_startup_trails` times.
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pfnopt/samplers/tpe.py`
  Content:
  ```
  1 import math
  2 import numpy
  3 from typing import List  # NOQA
  4 from typing import Optional  # NOQA
  5 
  6 from pfnopt import distributions  # NOQA
  7 from pfnopt.samplers import _hyperopt
  8 from pfnopt.samplers import base
  9 from pfnopt.samplers import random
  10 from pfnopt.storages.base import BaseStorage  # NOQA
  11 
  12 
  13 class TPESampler(base.BaseSampler):
  14 
  15     def __init__(self,
  16                  prior_weight=_hyperopt.default_prior_weight,
  17                  n_startup_trials=_hyperopt.default_n_startup_trials,
  18                  n_ei_candidates=_hyperopt.default_n_ei_candidates,
  19                  gamma=_hyperopt.default_gamma,
  20                  seed=None):
  21         # type: (float, int, int, float, Optional[int]) -> None
  22         self.prior_weight = prior_weight
  23         self.n_startup_trials = n_startup_trials
  24         self.n_ei_candidates = n_ei_candidates
  25         self.gamma = gamma
  26         self.seed = seed
  27 
  28         self.rng = numpy.random.RandomState(seed)
  29         self.random_sampler = random.RandomSampler(seed=seed)
  30 
  31     def sample(self, storage, study_id, param_name, param_distribution):
  32         # type: (BaseStorage, int, str, distributions.BaseDistribution) -> float
  33         observation_pairs = storage.get_trial_param_result_pairs(
  34             study_id, param_name)
  35         n = len(observation_pairs)
  36 
  37         # TODO(Akiba): this behavior is slightly different from hyperopt
  38         if n < self.n_startup_trials:
  39             return self.random_sampler.sample(storage, study_id, param_name, param_distribution)
  40 
  41         below_param_values, above_param_values = _hyperopt.ap_filter_trials(
  42             range(n), [p[0] for p in observation_pairs],
  43             range(n), [p[1] for p in observation_pairs],
  44             self.gamma)
  45 
  46         if isinstance(param_distribution, distributions.UniformDistribution):
  47             return self._sample_uniform(
  48                 param_distribution, below_param_values, above_param_values)
  49         elif isinstance(param_distribution, distributions.LogUniformDistribution):
  50             return self._sample_loguniform(
  51                 param_distribution, below_param_values, above_param_values)
  52         elif isinstance(param_distribution, distributions.CategoricalDistribution):
  53             return self._sample_categorical(
  54                 param_distribution, below_param_values, above_param_values)
  55         else:
  56             raise NotImplementedError
  57 
  58     def _sample_uniform(self, distribution, below, above):
  59         # type: (distributions.UniformDistribution, List[float], List[float]) -> float
  60         return _hyperopt.sample_uniform(
  61             obs_below=below, obs_above=above, prior_weight=self.prior_weight,
  62             low=distribution.low, high=distribution.high,
  63             size=(self.n_ei_candidates,), rng=self.rng)
  64 
  65     def _sample_loguniform(self, distribution, below, above):
  66         # type: (distributions.LogUniformDistribution, List[float], List[float]) -> float
  67 
  68         return _hyperopt.sample_loguniform(
  69             obs_below=below, obs_above=above, prior_weight=self.prior_weight,
  70             # `sample_loguniform` generates values in [exp(low), exp(high)]
  71             low=math.log(distribution.low),
  72             high=math.log(distribution.high),
  73             size=(self.n_ei_candidates,), rng=self.rng)
  74 
  75     def _sample_categorical(self, distribution, below, above):
  76         # type: (distributions.CategoricalDistribution, List[float], List[float]) -> float
  77         choices = distribution.choices
  78         below = list(map(int, below))
  79         above = list(map(int, above))
  80         idx = _hyperopt.sample_categorical(
  81             obs_below=below, obs_above=above, prior_weight=self.prior_weight,
  82             upper=len(choices), size=(self.n_ei_candidates, ), rng=self.rng)
  83         return idx
  84
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pfnopt/samplers/tpe.py b/pfnopt/samplers/tpe.py
  --- a/pfnopt/samplers/tpe.py
  +++ b/pfnopt/samplers/tpe.py
  @@ -80,4 +80,4 @@
           idx = _hyperopt.sample_categorical(
               obs_below=below, obs_above=above, prior_weight=self.prior_weight,
               upper=len(choices), size=(self.n_ei_candidates, ), rng=self.rng)
  -        return idx
  +        return int(idx)
  
verification_info: {"golden_diff": "diff --git a/pfnopt/samplers/tpe.py b/pfnopt/samplers/tpe.py\n--- a/pfnopt/samplers/tpe.py\n+++ b/pfnopt/samplers/tpe.py\n@@ -80,4 +80,4 @@\n         idx = _hyperopt.sample_categorical(\n             obs_below=below, obs_above=above, prior_weight=self.prior_weight,\n             upper=len(choices), size=(self.n_ei_candidates, ), rng=self.rng)\n-        return idx\n+        return int(idx)\n", "issue": "`TPESampler._sample_categorical` fails with PostgreSQL backend\n`TPESampler._sample_categorical` fails with PostgreSQL backend. This happens because:\r\n- `TPESampler._sample_categorical` returns an integer as `numpy.int32`.\r\n- The integer value is input to storage class without any cast.\r\n- SQLAlchemy with psycopg2 backend does not support `numpy.int32` input but does `int` one.\r\n\r\n**Repro Steps**\r\nWith any objective function using categorical sampling (e.g., example one in `chainer_mnist.py`), invoke `minimize` as:\r\n```\r\nstudy = pfnopt.create_study(storage=SOME_POSTGRES_URL)\r\npfnopt.minimize(objective, n_trials=100, study=study)\r\n```\r\n\r\nIt fails after running trials `n_startup_trails` times.\n", "before_files": [{"content": "import math\nimport numpy\nfrom typing import List  # NOQA\nfrom typing import Optional  # NOQA\n\nfrom pfnopt import distributions  # NOQA\nfrom pfnopt.samplers import _hyperopt\nfrom pfnopt.samplers import base\nfrom pfnopt.samplers import random\nfrom pfnopt.storages.base import BaseStorage  # NOQA\n\n\nclass TPESampler(base.BaseSampler):\n\n    def __init__(self,\n                 prior_weight=_hyperopt.default_prior_weight,\n                 n_startup_trials=_hyperopt.default_n_startup_trials,\n                 n_ei_candidates=_hyperopt.default_n_ei_candidates,\n                 gamma=_hyperopt.default_gamma,\n                 seed=None):\n        # type: (float, int, int, float, Optional[int]) -> None\n        self.prior_weight = prior_weight\n        self.n_startup_trials = n_startup_trials\n        self.n_ei_candidates = n_ei_candidates\n        self.gamma = gamma\n        self.seed = seed\n\n        self.rng = numpy.random.RandomState(seed)\n        self.random_sampler = random.RandomSampler(seed=seed)\n\n    def sample(self, storage, study_id, param_name, param_distribution):\n        # type: (BaseStorage, int, str, distributions.BaseDistribution) -> float\n        observation_pairs = storage.get_trial_param_result_pairs(\n            study_id, param_name)\n        n = len(observation_pairs)\n\n        # TODO(Akiba): this behavior is slightly different from hyperopt\n        if n < self.n_startup_trials:\n            return self.random_sampler.sample(storage, study_id, param_name, param_distribution)\n\n        below_param_values, above_param_values = _hyperopt.ap_filter_trials(\n            range(n), [p[0] for p in observation_pairs],\n            range(n), [p[1] for p in observation_pairs],\n            self.gamma)\n\n        if isinstance(param_distribution, distributions.UniformDistribution):\n            return self._sample_uniform(\n                param_distribution, below_param_values, above_param_values)\n        elif isinstance(param_distribution, distributions.LogUniformDistribution):\n            return self._sample_loguniform(\n                param_distribution, below_param_values, above_param_values)\n        elif isinstance(param_distribution, distributions.CategoricalDistribution):\n            return self._sample_categorical(\n                param_distribution, below_param_values, above_param_values)\n        else:\n            raise NotImplementedError\n\n    def _sample_uniform(self, distribution, below, above):\n        # type: (distributions.UniformDistribution, List[float], List[float]) -> float\n        return _hyperopt.sample_uniform(\n            obs_below=below, obs_above=above, prior_weight=self.prior_weight,\n            low=distribution.low, high=distribution.high,\n            size=(self.n_ei_candidates,), rng=self.rng)\n\n    def _sample_loguniform(self, distribution, below, above):\n        # type: (distributions.LogUniformDistribution, List[float], List[float]) -> float\n\n        return _hyperopt.sample_loguniform(\n            obs_below=below, obs_above=above, prior_weight=self.prior_weight,\n            # `sample_loguniform` generates values in [exp(low), exp(high)]\n            low=math.log(distribution.low),\n            high=math.log(distribution.high),\n            size=(self.n_ei_candidates,), rng=self.rng)\n\n    def _sample_categorical(self, distribution, below, above):\n        # type: (distributions.CategoricalDistribution, List[float], List[float]) -> float\n        choices = distribution.choices\n        below = list(map(int, below))\n        above = list(map(int, above))\n        idx = _hyperopt.sample_categorical(\n            obs_below=below, obs_above=above, prior_weight=self.prior_weight,\n            upper=len(choices), size=(self.n_ei_candidates, ), rng=self.rng)\n        return idx\n", "path": "pfnopt/samplers/tpe.py"}], "after_files": [{"content": "import math\nimport numpy\nfrom typing import List  # NOQA\nfrom typing import Optional  # NOQA\n\nfrom pfnopt import distributions  # NOQA\nfrom pfnopt.samplers import _hyperopt\nfrom pfnopt.samplers import base\nfrom pfnopt.samplers import random\nfrom pfnopt.storages.base import BaseStorage  # NOQA\n\n\nclass TPESampler(base.BaseSampler):\n\n    def __init__(self,\n                 prior_weight=_hyperopt.default_prior_weight,\n                 n_startup_trials=_hyperopt.default_n_startup_trials,\n                 n_ei_candidates=_hyperopt.default_n_ei_candidates,\n                 gamma=_hyperopt.default_gamma,\n                 seed=None):\n        # type: (float, int, int, float, Optional[int]) -> None\n        self.prior_weight = prior_weight\n        self.n_startup_trials = n_startup_trials\n        self.n_ei_candidates = n_ei_candidates\n        self.gamma = gamma\n        self.seed = seed\n\n        self.rng = numpy.random.RandomState(seed)\n        self.random_sampler = random.RandomSampler(seed=seed)\n\n    def sample(self, storage, study_id, param_name, param_distribution):\n        # type: (BaseStorage, int, str, distributions.BaseDistribution) -> float\n        observation_pairs = storage.get_trial_param_result_pairs(\n            study_id, param_name)\n        n = len(observation_pairs)\n\n        # TODO(Akiba): this behavior is slightly different from hyperopt\n        if n < self.n_startup_trials:\n            return self.random_sampler.sample(storage, study_id, param_name, param_distribution)\n\n        below_param_values, above_param_values = _hyperopt.ap_filter_trials(\n            range(n), [p[0] for p in observation_pairs],\n            range(n), [p[1] for p in observation_pairs],\n            self.gamma)\n\n        if isinstance(param_distribution, distributions.UniformDistribution):\n            return self._sample_uniform(\n                param_distribution, below_param_values, above_param_values)\n        elif isinstance(param_distribution, distributions.LogUniformDistribution):\n            return self._sample_loguniform(\n                param_distribution, below_param_values, above_param_values)\n        elif isinstance(param_distribution, distributions.CategoricalDistribution):\n            return self._sample_categorical(\n                param_distribution, below_param_values, above_param_values)\n        else:\n            raise NotImplementedError\n\n    def _sample_uniform(self, distribution, below, above):\n        # type: (distributions.UniformDistribution, List[float], List[float]) -> float\n        return _hyperopt.sample_uniform(\n            obs_below=below, obs_above=above, prior_weight=self.prior_weight,\n            low=distribution.low, high=distribution.high,\n            size=(self.n_ei_candidates,), rng=self.rng)\n\n    def _sample_loguniform(self, distribution, below, above):\n        # type: (distributions.LogUniformDistribution, List[float], List[float]) -> float\n\n        return _hyperopt.sample_loguniform(\n            obs_below=below, obs_above=above, prior_weight=self.prior_weight,\n            # `sample_loguniform` generates values in [exp(low), exp(high)]\n            low=math.log(distribution.low),\n            high=math.log(distribution.high),\n            size=(self.n_ei_candidates,), rng=self.rng)\n\n    def _sample_categorical(self, distribution, below, above):\n        # type: (distributions.CategoricalDistribution, List[float], List[float]) -> float\n        choices = distribution.choices\n        below = list(map(int, below))\n        above = list(map(int, above))\n        idx = _hyperopt.sample_categorical(\n            obs_below=below, obs_above=above, prior_weight=self.prior_weight,\n            upper=len(choices), size=(self.n_ei_candidates, ), rng=self.rng)\n        return int(idx)\n", "path": "pfnopt/samplers/tpe.py"}]}