#postgresql #go #go-chi
#postgresql #Вперед #go-chi
Вопрос:
Я пытаюсь сохранить удаленный IP-адрес входящего запроса в Postgres. Я использую chi
и sqlc
.
Вот миграция:
CREATE TABLE IF NOT EXISTS ips (
id bigserial PRIMARY KEY,
ip INET
);
И это запрос вставки:
-- name: CreateIp :one
INSERT INTO ips (
ip
) VALUES (
$1
) RETURNING *;
Это структура для параметров:
type CreateIpParams struct {
Ip net.IP `json:"ip"`
}
Получить IP и проанализировать его:
...
// Get IP from RemoteAddr
ip, _, _ := net.SplitHostPort(r.RemoteAddr)
log.Println(" >> ip:", reflect.ValueOf(ip)) // ::1
log.Println(" >> ip.TypeOf:", reflect.TypeOf(ip)) // string
if netIp := net.ParseIP(ip); netIp != nil {
params.Ip = netIp
log.Println(" >> netIp:", reflect.ValueOf(netIp)) // ::1
log.Println(" >> netIp.TypeOf:", reflect.TypeOf(netIp)) // net.IP
}
...
Когда я сделал POST
запрос, он возвращает:
"error": "pq: invalid byte sequence for encoding "UTF8": 0x00"
Если я удалил этот блок кода без сохранения ip вообще:
"error": "pq: invalid input syntax for type inet: """
Я попытался обрезать ip
с strings.TrimSpace(ip)
помощью, но не помогает.
Код с sqlc
сохранением.
...
params := amp;db.CreateIpParams{}
// Get IP from RemoteAddr
ip, _, _ := net.SplitHostPort(r.RemoteAddr)
if netIp := net.ParseIP(ip); netIp != nil {
params.Ip = netIp
}
if _, err := db.NewPg(pg).CreateIp(context.Background(), *params); err != nil {
render.Render(w, r, ErrRender(err))
return
}
CreateIp
код и Ip
структура:
// db/user.sql.go
func (q *Queries) CreateIp(ctx context.Context, arg CreateIpParams) (Ip, error) {
row := q.queryRow(ctx, q.createIpStmt, createIp,
arg.Ip,
)
var i Ip
err := row.Scan(
amp;i.Ip,
)
return i, err
}
// db/models.go
type Ip struct {
ID int64 `json:"id"`
Ip net.IP `json:"ip"`
}
Комментарии:
1. Извините за это, я обновил код, с помощью которого сохраняю
sqlc
.2. Можете ли вы показать, как
CreateIp
это выглядит, независимо от того, сгенерировано оно или написано от руки?3. Конечно, я добавил.
4. Выглядит нормально, еще одна вещь: происходит ли анализ и сохранение параметров в одной и той же функции? или это делается отдельными функциями? Если это делается с помощью отдельной функции, вы уверены, что передаете указатель на эту функцию? Попробуйте добавить оператор log / print к сгенерированному
CreateIp
, чтобы узнатьarg
Ip
, установлено ли поле или нет, если нет, то это будет означать, что вы передаете копии параметров где-то, где вместо этого вы должны передавать указатели.5. @mkopriva Да, теперь я понимаю, что ты имеешь в виду. Спасибо за помощь, брат / сестра. 🙂