diff --git a/migrations/2025-02-11-163554_fix-num-versions-trigger/down.sql b/migrations/2025-02-11-163554_fix-num-versions-trigger/down.sql
new file mode 100644
index 00000000000..8193ba6193e
--- /dev/null
+++ b/migrations/2025-02-11-163554_fix-num-versions-trigger/down.sql
@@ -0,0 +1 @@
+DROP FUNCTION IF EXISTS update_num_versions_from_versions CASCADE;
diff --git a/migrations/2025-02-11-163554_fix-num-versions-trigger/up.sql b/migrations/2025-02-11-163554_fix-num-versions-trigger/up.sql
new file mode 100644
index 00000000000..d6699259e9f
--- /dev/null
+++ b/migrations/2025-02-11-163554_fix-num-versions-trigger/up.sql
@@ -0,0 +1,16 @@
+CREATE OR REPLACE FUNCTION update_num_versions_from_versions() RETURNS TRIGGER AS $$
+BEGIN
+ IF (TG_OP = 'INSERT') THEN
+ INSERT INTO default_versions (crate_id, version_id, num_versions)
+ VALUES (NEW.crate_id, NEW.id, 1)
+ ON CONFLICT (crate_id) DO UPDATE
+ SET num_versions = default_versions.num_versions + 1;
+ RETURN NEW;
+ ELSIF (TG_OP = 'DELETE') THEN
+ UPDATE default_versions
+ SET num_versions = num_versions - 1
+ WHERE crate_id = OLD.crate_id;
+ RETURN OLD;
+ END IF;
+END
+$$ LANGUAGE plpgsql;
diff --git a/src/tests/krate/publish/basics.rs b/src/tests/krate/publish/basics.rs
index ca932cd9de8..bf674e0fc4c 100644
--- a/src/tests/krate/publish/basics.rs
+++ b/src/tests/krate/publish/basics.rs
@@ -2,7 +2,7 @@ use crate::schema::versions_published_by;
use crate::tests::builders::{CrateBuilder, PublishBuilder};
use crate::tests::util::{RequestHelper, TestApp};
use diesel::QueryDsl;
-use diesel_async::RunQueryDsl;
+use diesel_async::{AsyncPgConnection, RunQueryDsl};
use googletest::prelude::*;
use http::StatusCode;
use insta::{assert_json_snapshot, assert_snapshot};
@@ -116,23 +116,12 @@ async fn new_krate_twice() {
// The primary purpose is to verify that the `default_version` we provide is as expected.
#[tokio::test(flavor = "multi_thread")]
async fn new_krate_twice_alt() {
- use crate::schema::default_versions;
-
let (app, _, _, token) = TestApp::full().with_token().await;
- let mut conn = app.db_conn().await;
let crate_to_publish =
PublishBuilder::new("foo_twice", "2.0.0").description("2.0.0 description");
token.publish_crate(crate_to_publish).await.good();
- let num_versions = default_versions::table
- .select(default_versions::num_versions)
- .load::