std::net::IpAddr cannot bind to INET (postgres) #4168
-
|
I have bound an IpAddr type to a column of type INET(postgres) as shown below, but sqlx is expecting an IpNetwork type. The official documentation states that the std::net::IpAddr type and INET type are compatible based on the ipnet features flag. https://docs.rs/sqlx/latest/sqlx/postgres/types/index.html#ipnet Am I using it wrong somehow? CREATE TABLE sensor_logs (
id SERIAL PRIMARY KEY,
host_name VARCHAR(128) NOT NULL,
ip_address INET NOT NULL,
collected TIMESTAMP NOT NULL,
extra JSONB
);let result = sqlx::query!(
r#"
INSERT INTO sensor_logs (host_name, ip_address, collected, extra)
VALUES ($1, $2, $3, $4)
RETURNING id
"#,
sensor_log_row.host_name,
IpAddr::V4("192.168.1.2".parse().unwrap()), // here
sensor_log_row.collected,
extra_json
)
.fetch_one(self.txn().as_mut())
.await?; |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
|
The reason you're seeing a mismatch is that Postgres's To fix this, you should use the use ipnetwork::IpNetwork;
// Convert your IpAddr into the network type sqlx expects
let ip_param: IpNetwork = sensor_log_row.ip_address.into();
let result = sqlx::query!(
r#"INSERT INTO sensor_logs (ip_address) VALUES ($1) RETURNING id"#,
ip_param
)
.fetch_one(pool)
.await?;If you don't want to bring in another type, you can use a type cast directly in your SQL string. This tells the let result = sqlx::query!(
r#"INSERT INTO sensor_logs (ip_address) VALUES ($1::inet) RETURNING id"#,
sensor_log_row.ip_address // std::net::IpAddr works here with the cast
)
.fetch_one(pool)
.await?;Make sure you have |
Beta Was this translation helpful? Give feedback.
-
|
Thank you for your advice. This time, I solved the problem by implementing ipnet::IpNet. As you pointed out, it seems that casting std::net::IpAddr to ($1::inet) in the SQL query However, because collecting IP addresses requires various complex internal company procedures, |
Beta Was this translation helpful? Give feedback.
The reason you're seeing a mismatch is that Postgres's
INETtype isn't just an IP address: it's an IP address plus a network prefix (like/32or/128). Whilestd::net::IpAddrrepresents the address, it doesn't carry that prefix information, which is whysqlxdefaults to more specific types.To fix this, you should use the
IpNetworktype from theipnetworkcrate (if you have that feature enabled insqlx). It converts seamlessly fromIpAddr: