← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:stormify-branchmergeproposal into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:stormify-branchmergeproposal into launchpad:master.

Commit message:
Convert BranchMergeProposal to Storm

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/446309
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-branchmergeproposal into launchpad:master.
diff --git a/lib/lp/code/interfaces/branchmergeproposal.py b/lib/lp/code/interfaces/branchmergeproposal.py
index 20b4ceb..e65eef6 100644
--- a/lib/lp/code/interfaces/branchmergeproposal.py
+++ b/lib/lp/code/interfaces/branchmergeproposal.py
@@ -93,16 +93,16 @@ class IBranchMergeProposalPublic(IPrivacy):
         readonly=True,
         description=_("The tracking number for this merge proposal."),
     )
-    source_branchID = Int(
+    source_branch_id = Int(
         title=_("Source branch ID"), required=False, readonly=True
     )
-    source_git_repositoryID = Int(
+    source_git_repository_id = Int(
         title=_("Source Git repository ID"), required=False, readonly=True
     )
-    prerequisite_branchID = Int(
+    prerequisite_branch_id = Int(
         title=_("Prerequisite branch ID"), required=False, readonly=True
     )
-    prerequisite_git_repositoryID = Int(
+    prerequisite_git_repository_id = Int(
         title=_("Prerequisite Git repository ID"),
         required=False,
         readonly=True,
diff --git a/lib/lp/code/mail/codehandler.py b/lib/lp/code/mail/codehandler.py
index 7a8a3f0..6eb574a 100644
--- a/lib/lp/code/mail/codehandler.py
+++ b/lib/lp/code/mail/codehandler.py
@@ -10,12 +10,12 @@ from zope.component import getUtility
 from zope.interface import implementer
 from zope.security.interfaces import Unauthorized
 
+from lp.app.errors import NotFoundError
 from lp.code.adapters.branch import BranchMergeProposalNoPreviewDiffDelta
 from lp.code.enums import CodeReviewVote
 from lp.code.errors import UserNotBranchReviewer
 from lp.code.interfaces.branchmergeproposal import IBranchMergeProposalGetter
 from lp.services.config import config
-from lp.services.database.sqlobject import SQLObjectNotFound
 from lp.services.mail.commands import EmailCommand, EmailCommandCollection
 from lp.services.mail.helpers import (
     IncomingEmailError,
@@ -42,7 +42,7 @@ class InvalidBranchMergeProposalAddress(BadBranchMergeProposalAddress):
     """The user-supplied address is not an acceptable value."""
 
 
-class NonExistantBranchMergeProposalAddress(BadBranchMergeProposalAddress):
+class NonExistentBranchMergeProposalAddress(BadBranchMergeProposalAddress):
     """The BranchMergeProposal specified by the address does not exist."""
 
 
@@ -310,7 +310,7 @@ class CodeHandler:
         user = getUtility(ILaunchBag).user
         try:
             merge_proposal = self.getBranchMergeProposal(email_addr)
-        except NonExistantBranchMergeProposalAddress:
+        except NonExistentBranchMergeProposalAddress:
             send_process_error_notification(
                 str(user.preferredemail.email),
                 "Submit Request Failure",
@@ -375,5 +375,5 @@ class CodeHandler:
         getter = getUtility(IBranchMergeProposalGetter)
         try:
             return getter.get(merge_proposal_id)
-        except SQLObjectNotFound:
-            raise NonExistantBranchMergeProposalAddress(email_addr)
+        except NotFoundError:
+            raise NonExistentBranchMergeProposalAddress(email_addr)
diff --git a/lib/lp/code/model/branch.py b/lib/lp/code/model/branch.py
index b9cfedc..b9f9b5f 100644
--- a/lib/lp/code/model/branch.py
+++ b/lib/lp/code/model/branch.py
@@ -134,7 +134,7 @@ from lp.services.database.datetimecol import UtcDateTimeCol
 from lp.services.database.decoratedresultset import DecoratedResultSet
 from lp.services.database.enumcol import DBEnum
 from lp.services.database.interfaces import IPrimaryStore, IStore
-from lp.services.database.sqlbase import SQLBase, sqlvalues
+from lp.services.database.sqlbase import SQLBase
 from lp.services.database.sqlobject import ForeignKey, IntCol, StringCol
 from lp.services.database.stormexpr import Array, ArrayAgg, ArrayIntersects
 from lp.services.helpers import shortlist
@@ -559,12 +559,14 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
     @property
     def dependent_branches(self):
         """See `IBranch`."""
-        return BranchMergeProposal.select(
-            """
-            BranchMergeProposal.dependent_branch = %s AND
-            BranchMergeProposal.queue_status NOT IN %s
-            """
-            % sqlvalues(self, BRANCH_MERGE_PROPOSAL_FINAL_STATES)
+        return Store.of(self).find(
+            BranchMergeProposal,
+            BranchMergeProposal.prerequisite_branch == self,
+            Not(
+                BranchMergeProposal.queue_status.is_in(
+                    BRANCH_MERGE_PROPOSAL_FINAL_STATES
+                )
+            ),
         )
 
     def getMergeProposals(
@@ -942,7 +944,9 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
             )
         # Cannot use self.landing_candidates, because it ignores merged
         # merge proposals.
-        for merge_proposal in BranchMergeProposal.selectBy(target_branch=self):
+        for merge_proposal in Store.of(self).find(
+            BranchMergeProposal, target_branch=self
+        ):
             deletion_operations.append(
                 DeletionCallable(
                     merge_proposal,
@@ -953,8 +957,8 @@ class Branch(SQLBase, WebhookTargetMixin, BzrIdentityMixin):
                     merge_proposal.deleteProposal,
                 )
             )
-        for merge_proposal in BranchMergeProposal.selectBy(
-            prerequisite_branch=self
+        for merge_proposal in Store.of(self).find(
+            BranchMergeProposal, prerequisite_branch=self
         ):
             alteration_operations.append(ClearDependentBranch(merge_proposal))
 
diff --git a/lib/lp/code/model/branchcollection.py b/lib/lp/code/model/branchcollection.py
index 8ffbb63..55cbb0c 100644
--- a/lib/lp/code/model/branchcollection.py
+++ b/lib/lp/code/model/branchcollection.py
@@ -431,14 +431,16 @@ class GenericBranchCollection:
                 Join(
                     BranchMergeProposal,
                     And(
-                        Branch.id == BranchMergeProposal.source_branchID,
+                        Branch.id == BranchMergeProposal.source_branch_id,
                         *(
                             self._branch_filter_expressions
                             + self._asymmetric_filter_expressions
                         ),
                     ),
                 ),
-                Join(Target, Target.id == BranchMergeProposal.target_branchID),
+                Join(
+                    Target, Target.id == BranchMergeProposal.target_branch_id
+                ),
             ]
         )
         expressions = self._getBranchVisibilityExpression()
@@ -446,7 +448,7 @@ class GenericBranchCollection:
         if for_branches is not None:
             branch_ids = [branch.id for branch in for_branches]
             expressions.append(
-                BranchMergeProposal.source_branchID.is_in(branch_ids)
+                BranchMergeProposal.source_branch_id.is_in(branch_ids)
             )
         if target_branch is not None:
             expressions.append(
@@ -467,7 +469,7 @@ class GenericBranchCollection:
                     == BranchRevision.sequence,
                     BranchRevision.revision_id == Revision.id,
                     BranchRevision.branch_id
-                    == BranchMergeProposal.target_branchID,
+                    == BranchMergeProposal.target_branch_id,
                     Revision.revision_id == merged_revision,
                 ]
             )
@@ -512,7 +514,7 @@ class GenericBranchCollection:
             # Need to filter on Branch beyond the with constraints.
             expressions += self._asymmetric_filter_expressions
             expressions.append(
-                BranchMergeProposal.source_branchID == Branch.id
+                BranchMergeProposal.source_branch_id == Branch.id
             )
             tables.append(Branch)
             tables.extend(self._asymmetric_tables.values())
@@ -568,12 +570,14 @@ class GenericBranchCollection:
 
         expressions = [
             CodeReviewVoteReference.reviewer == reviewer,
-            BranchMergeProposal.source_branchID.is_in(self._getBranchSelect()),
+            BranchMergeProposal.source_branch_id.is_in(
+                self._getBranchSelect()
+            ),
         ]
         visibility = self._getBranchVisibilityExpression()
         if visibility:
             expressions.append(
-                BranchMergeProposal.target_branchID.is_in(
+                BranchMergeProposal.target_branch_id.is_in(
                     Select(Branch.id, visibility)
                 )
             )
diff --git a/lib/lp/code/model/branchmergeproposal.py b/lib/lp/code/model/branchmergeproposal.py
index bf927c8..7fb2176 100644
--- a/lib/lp/code/model/branchmergeproposal.py
+++ b/lib/lp/code/model/branchmergeproposal.py
@@ -11,12 +11,13 @@ __all__ = [
 
 import sys
 from collections import defaultdict
+from datetime import timezone
 from email.utils import make_msgid
 from operator import attrgetter
 
 from lazr.lifecycle.event import ObjectCreatedEvent, ObjectDeletedEvent
 from storm.expr import SQL, And, Desc, Join, LeftJoin, Not, Or, Select
-from storm.locals import Int, Reference
+from storm.locals import DateTime, Int, Reference, Unicode
 from storm.store import Store
 from zope.component import getUtility
 from zope.error.interfaces import IErrorReportingUtility
@@ -82,11 +83,10 @@ from lp.registry.model.person import Person
 from lp.services.config import config
 from lp.services.database.bulk import load, load_referencing, load_related
 from lp.services.database.constants import DEFAULT, UTC_NOW
-from lp.services.database.datetimecol import UtcDateTimeCol
 from lp.services.database.enumcol import DBEnum
 from lp.services.database.interfaces import IPrimaryStore, IStore
-from lp.services.database.sqlbase import SQLBase, quote
-from lp.services.database.sqlobject import ForeignKey, IntCol, StringCol
+from lp.services.database.sqlbase import quote
+from lp.services.database.stormbase import StormBase
 from lp.services.helpers import shortlist
 from lp.services.job.interfaces.job import JobStatus
 from lp.services.job.model.job import Job
@@ -160,65 +160,62 @@ class TooManyRelatedBugs(Exception):
 
 
 @implementer(IBranchMergeProposal, IHasBranchTarget)
-class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
+class BranchMergeProposal(StormBase, BugLinkTargetMixin):
     """A relationship between a person and a branch."""
 
-    _table = "BranchMergeProposal"
-    _defaultOrder = ["-date_created", "id"]
+    __storm_table__ = "BranchMergeProposal"
+    __storm_order__ = ("-date_created", "id")
 
-    registrant = ForeignKey(
-        dbName="registrant",
-        foreignKey="Person",
-        storm_validator=validate_public_person,
-        notNull=True,
-    )
+    id = Int(primary=True)
 
-    source_branch = ForeignKey(
-        dbName="source_branch", foreignKey="Branch", notNull=False
+    registrant_id = Int(
+        name="registrant", validator=validate_public_person, allow_none=False
     )
-    source_git_repositoryID = Int(
+    registrant = Reference(registrant_id, "Person.id")
+
+    source_branch_id = Int(name="source_branch", allow_none=True)
+    source_branch = Reference(source_branch_id, "Branch.id")
+    source_git_repository_id = Int(
         name="source_git_repository", allow_none=True
     )
     source_git_repository = Reference(
-        source_git_repositoryID, "GitRepository.id"
+        source_git_repository_id, "GitRepository.id"
     )
-    source_git_path = StringCol(
-        dbName="source_git_path", default=None, notNull=False
+    source_git_path = Unicode(
+        name="source_git_path", default=None, allow_none=True
     )
-    source_git_commit_sha1 = StringCol(
-        dbName="source_git_commit_sha1", default=None, notNull=False
+    source_git_commit_sha1 = Unicode(
+        name="source_git_commit_sha1", default=None, allow_none=True
     )
 
-    target_branch = ForeignKey(
-        dbName="target_branch", foreignKey="Branch", notNull=False
-    )
-    target_git_repositoryID = Int(
+    target_branch_id = Int(name="target_branch", allow_none=True)
+    target_branch = Reference(target_branch_id, "Branch.id")
+    target_git_repository_id = Int(
         name="target_git_repository", allow_none=True
     )
     target_git_repository = Reference(
-        target_git_repositoryID, "GitRepository.id"
+        target_git_repository_id, "GitRepository.id"
     )
-    target_git_path = StringCol(
-        dbName="target_git_path", default=None, notNull=False
+    target_git_path = Unicode(
+        name="target_git_path", default=None, allow_none=True
     )
-    target_git_commit_sha1 = StringCol(
-        dbName="target_git_commit_sha1", default=None, notNull=False
+    target_git_commit_sha1 = Unicode(
+        name="target_git_commit_sha1", default=None, allow_none=True
     )
 
-    prerequisite_branch = ForeignKey(
-        dbName="dependent_branch", foreignKey="Branch", notNull=False
-    )
-    prerequisite_git_repositoryID = Int(
+    prerequisite_branch_id = Int(name="dependent_branch", allow_none=True)
+    prerequisite_branch = Reference(prerequisite_branch_id, "Branch.id")
+    prerequisite_git_repository_id = Int(
         name="dependent_git_repository", allow_none=True
     )
     prerequisite_git_repository = Reference(
-        prerequisite_git_repositoryID, "GitRepository.id"
+        prerequisite_git_repository_id, "GitRepository.id"
     )
-    prerequisite_git_path = StringCol(
-        dbName="dependent_git_path", default=None, notNull=False
+    prerequisite_git_path = Unicode(
+        name="dependent_git_path", default=None, allow_none=True
     )
-    prerequisite_git_commit_sha1 = StringCol(
-        dbName="dependent_git_commit_sha1", default=None, notNull=False
+    prerequisite_git_commit_sha1 = Unicode(
+        name="dependent_git_commit_sha1", default=None, allow_none=True
     )
 
     @property
@@ -303,9 +300,9 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         else:
             return self.source_git_repository
 
-    description = StringCol(default=None)
+    description = Unicode(default=None)
 
-    whiteboard = StringCol(default=None)
+    whiteboard = Unicode(default=None)
 
     queue_status = DBEnum(
         enum=BranchMergeProposalStatus,
@@ -326,13 +323,13 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
             for obj in objects
         )
 
-    reviewer = ForeignKey(
-        dbName="reviewer",
-        foreignKey="Person",
-        storm_validator=validate_person,
-        notNull=False,
+    reviewer_id = Int(
+        name="reviewer",
+        validator=validate_person,
+        allow_none=True,
         default=None,
     )
+    reviewer = Reference(reviewer_id, "Person.id")
 
     @property
     def next_preview_diff_job(self):
@@ -356,13 +353,13 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         else:
             return None
 
-    reviewed_revision_id = StringCol(default=None)
+    reviewed_revision_id = Unicode(default=None)
 
-    commit_message = StringCol(default=None)
+    commit_message = Unicode(default=None)
 
-    date_merged = UtcDateTimeCol(default=None)
-    merged_revno = IntCol(default=None)
-    merged_revision_id = StringCol(default=None)
+    date_merged = DateTime(default=None, tzinfo=timezone.utc)
+    merged_revno = Int(default=None)
+    merged_revision_id = Unicode(default=None)
 
     @property
     def merged_revision(self):
@@ -372,13 +369,56 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         else:
             return self.merged_revision_id
 
-    merge_reporter = ForeignKey(
-        dbName="merge_reporter",
-        foreignKey="Person",
-        storm_validator=validate_public_person,
-        notNull=False,
+    merge_reporter_id = Int(
+        name="merge_reporter",
+        validator=validate_public_person,
+        allow_none=True,
         default=None,
     )
+    merge_reporter = Reference(merge_reporter_id, "Person.id")
+
+    def __init__(
+        self,
+        registrant,
+        source_branch=None,
+        source_git_repository=None,
+        source_git_path=None,
+        source_git_commit_sha1=None,
+        target_branch=None,
+        target_git_repository=None,
+        target_git_path=None,
+        target_git_commit_sha1=None,
+        prerequisite_branch=None,
+        prerequisite_git_repository=None,
+        prerequisite_git_path=None,
+        prerequisite_git_commit_sha1=None,
+        description=None,
+        whiteboard=None,
+        queue_status=DEFAULT,
+        commit_message=None,
+        date_created=DEFAULT,
+        date_review_requested=None,
+    ):
+        super().__init__()
+        self.registrant = registrant
+        self.source_branch = source_branch
+        self.source_git_repository = source_git_repository
+        self.source_git_path = source_git_path
+        self.source_git_commit_sha1 = source_git_commit_sha1
+        self.target_branch = target_branch
+        self.target_git_repository = target_git_repository
+        self.target_git_path = target_git_path
+        self.target_git_commit_sha1 = target_git_commit_sha1
+        self.prerequisite_branch = prerequisite_branch
+        self.prerequisite_git_repository = prerequisite_git_repository
+        self.prerequisite_git_path = prerequisite_git_path
+        self.prerequisite_git_commit_sha1 = prerequisite_git_commit_sha1
+        self.description = description
+        self.whiteboard = whiteboard
+        self.queue_status = queue_status
+        self.commit_message = commit_message
+        self.date_created = date_created
+        self.date_review_requested = date_review_requested
 
     @property
     def bugs(self):
@@ -557,22 +597,24 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
     def address(self):
         return "mp+%d@%s" % (self.id, config.launchpad.code_domain)
 
-    superseded_by = ForeignKey(
-        dbName="superseded_by",
-        foreignKey="BranchMergeProposal",
-        notNull=False,
-        default=None,
-    )
+    superseded_by_id = Int(name="superseded_by", allow_none=True, default=None)
+    superseded_by = Reference(superseded_by_id, "BranchMergeProposal.id")
 
-    _supersedes = Reference("<primary key>", "superseded_by", on_remote=True)
+    _supersedes = Reference("id", "superseded_by_id", on_remote=True)
 
     @cachedproperty
     def supersedes(self):
         return self._supersedes
 
-    date_created = UtcDateTimeCol(notNull=True, default=DEFAULT)
-    date_review_requested = UtcDateTimeCol(notNull=False, default=None)
-    date_reviewed = UtcDateTimeCol(notNull=False, default=None)
+    date_created = DateTime(
+        allow_none=False, default=DEFAULT, tzinfo=timezone.utc
+    )
+    date_review_requested = DateTime(
+        allow_none=True, default=None, tzinfo=timezone.utc
+    )
+    date_reviewed = DateTime(
+        allow_none=True, default=None, tzinfo=timezone.utc
+    )
 
     @property
     def target(self):
@@ -584,7 +626,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
             # although it has similar semantics.
             return self.source_git_repository.namespace
 
-    root_message_id = StringCol(default=None)
+    root_message_id = Unicode(default=None)
 
     @property
     def title(self):
@@ -923,10 +965,10 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         self._transitionToState(
             BranchMergeProposalStatus.SUPERSEDED, registrant
         )
-        # This sync update is needed as the add landing target does
-        # a database query to identify if there are any active proposals
-        # with the same source and target branches.
-        self.syncUpdate()
+        # This flush is needed as the add landing target does a database
+        # query to identify if there are any active proposals with the same
+        # source and target branches.
+        Store.of(self).flush()
         review_requests = list(
             {(vote.reviewer, vote.review_type) for vote in self.votes}
         )
@@ -941,10 +983,10 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         )
         if not break_link:
             self.superseded_by = proposal
-        # This sync update is needed to ensure that the transitive
-        # properties of supersedes and superseded_by are visible to
-        # the old and the new proposal.
-        self.syncUpdate()
+        # This flush is needed to ensure that the transitive properties of
+        # supersedes and superseded_by are visible to the old and the new
+        # proposal.
+        Store.of(self).flush()
         return proposal
 
     def _normalizeReviewType(self, review_type):
@@ -1068,7 +1110,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         ):
             job.destroySelf()
         self._preview_diffs.remove()
-        self.destroySelf()
+        Store.of(self).remove(self)
 
     def getUnlandedSourceBranchRevisions(self):
         """See `IBranchMergeProposal`."""
@@ -1513,24 +1555,24 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         person_ids = set()
         for mp in branch_merge_proposals:
             ids.add(mp.id)
-            if mp.source_branchID is not None:
-                source_branch_ids.add(mp.source_branchID)
-            if mp.source_git_repositoryID is not None:
+            if mp.source_branch_id is not None:
+                source_branch_ids.add(mp.source_branch_id)
+            if mp.source_git_repository_id is not None:
                 git_ref_keys.add(
-                    (mp.source_git_repositoryID, mp.source_git_path)
+                    (mp.source_git_repository_id, mp.source_git_path)
                 )
                 git_ref_keys.add(
-                    (mp.target_git_repositoryID, mp.target_git_path)
+                    (mp.target_git_repository_id, mp.target_git_path)
                 )
-                if mp.prerequisite_git_repositoryID is not None:
+                if mp.prerequisite_git_repository_id is not None:
                     git_ref_keys.add(
                         (
-                            mp.prerequisite_git_repositoryID,
+                            mp.prerequisite_git_repository_id,
                             mp.prerequisite_git_path,
                         )
                     )
-            person_ids.add(mp.registrantID)
-            person_ids.add(mp.merge_reporterID)
+            person_ids.add(mp.registrant_id)
+            person_ids.add(mp.merge_reporter_id)
         git_repository_ids = {
             repository_id for repository_id, _ in git_ref_keys
         }
@@ -1538,15 +1580,15 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         branches = load_related(
             Branch,
             branch_merge_proposals,
-            ("target_branchID", "prerequisite_branchID", "source_branchID"),
+            ("target_branch_id", "prerequisite_branch_id", "source_branch_id"),
         )
         repositories = load_related(
             GitRepository,
             branch_merge_proposals,
             (
-                "target_git_repositoryID",
-                "prerequisite_git_repositoryID",
-                "source_git_repositoryID",
+                "target_git_repository_id",
+                "prerequisite_git_repository_id",
+                "source_git_repository_id",
             ),
         )
         load(GitRef, git_ref_keys)
@@ -1579,9 +1621,9 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
         # Preload other merge proposals that supersede these.
         supersedes_map = {}
         for other_mp in load_referencing(
-            BranchMergeProposal, branch_merge_proposals, ["superseded_byID"]
+            BranchMergeProposal, branch_merge_proposals, ["superseded_by_id"]
         ):
-            supersedes_map[other_mp.superseded_byID] = other_mp
+            supersedes_map[other_mp.superseded_by_id] = other_mp
         for mp in branch_merge_proposals:
             get_property_cache(mp).supersedes = supersedes_map.get(mp.id)
 
@@ -1643,7 +1685,10 @@ class BranchMergeProposalGetter:
     @staticmethod
     def get(id):
         """See `IBranchMergeProposalGetter`."""
-        return BranchMergeProposal.get(id)
+        mp = IStore(BranchMergeProposal).get(BranchMergeProposal, id)
+        if mp is None:
+            raise NotFoundError(id)
+        return mp
 
     @staticmethod
     def getProposalsForContext(context, status=None, visible_by_user=None):
@@ -1666,7 +1711,7 @@ class BranchMergeProposalGetter:
         """See `IBranchMergeProposalGetter`."""
         registrant_select = Select(
             BranchMergeProposal.id,
-            BranchMergeProposal.registrantID == participant.id,
+            BranchMergeProposal.registrant_id == participant.id,
         )
 
         review_select = Select(
diff --git a/lib/lp/code/model/gitcollection.py b/lib/lp/code/model/gitcollection.py
index 1885d75..2481410 100644
--- a/lib/lp/code/model/gitcollection.py
+++ b/lib/lp/code/model/gitcollection.py
@@ -367,7 +367,7 @@ class GenericGitCollection:
                     BranchMergeProposal,
                     And(
                         GitRepository.id
-                        == BranchMergeProposal.source_git_repositoryID,
+                        == BranchMergeProposal.source_git_repository_id,
                         *(
                             self._filter_expressions
                             + self._asymmetric_filter_expressions
@@ -376,7 +376,7 @@ class GenericGitCollection:
                 ),
                 Join(
                     Target,
-                    Target.id == BranchMergeProposal.target_git_repositoryID,
+                    Target.id == BranchMergeProposal.target_git_repository_id,
                 ),
             ]
         )
@@ -451,7 +451,8 @@ class GenericGitCollection:
             # Need to filter on GitRepository beyond the with constraints.
             expressions += self._asymmetric_filter_expressions
             expressions.append(
-                BranchMergeProposal.source_git_repositoryID == GitRepository.id
+                BranchMergeProposal.source_git_repository_id
+                == GitRepository.id
             )
             tables.append(GitRepository)
             tables.extend(self._asymmetric_tables.values())
@@ -507,14 +508,14 @@ class GenericGitCollection:
 
         expressions = [
             CodeReviewVoteReference.reviewer == reviewer,
-            BranchMergeProposal.source_git_repositoryID.is_in(
+            BranchMergeProposal.source_git_repository_id.is_in(
                 self._getRepositorySelect()
             ),
         ]
         visibility = self._getRepositoryVisibilityExpression()
         if visibility:
             expressions.append(
-                BranchMergeProposal.target_git_repositoryID.is_in(
+                BranchMergeProposal.target_git_repository_id.is_in(
                     Select(GitRepository.id, visibility)
                 )
             )
diff --git a/lib/lp/code/model/gitrepository.py b/lib/lp/code/model/gitrepository.py
index 37c5c08..8b3c3ea 100644
--- a/lib/lp/code/model/gitrepository.py
+++ b/lib/lp/code/model/gitrepository.py
@@ -1417,7 +1417,7 @@ class GitRepository(
         }
         updated = set()
         for kind in ("source", "target", "prerequisite"):
-            repository_name = "%s_git_repositoryID" % kind
+            repository_name = "%s_git_repository_id" % kind
             path_name = "%s_git_path" % kind
             commit_sha1_name = "%s_git_commit_sha1" % kind
             old_column = partial(getattr, BranchMergeProposal)
@@ -1958,8 +1958,8 @@ class GitRepository(
                 seen_merge_proposal_ids.add(merge_proposal.id)
         # Cannot use self.landing_candidates, because it ignores merged
         # merge proposals.
-        for merge_proposal in BranchMergeProposal.selectBy(
-            target_git_repository=self
+        for merge_proposal in Store.of(self).find(
+            BranchMergeProposal, target_git_repository=self
         ):
             if merge_proposal.id not in seen_merge_proposal_ids:
                 deletion_operations.append(
@@ -1973,8 +1973,8 @@ class GitRepository(
                     )
                 )
                 seen_merge_proposal_ids.add(merge_proposal.id)
-        for merge_proposal in BranchMergeProposal.selectBy(
-            prerequisite_git_repository=self
+        for merge_proposal in Store.of(self).find(
+            BranchMergeProposal, prerequisite_git_repository=self
         ):
             if merge_proposal.id not in seen_merge_proposal_ids:
                 alteration_operations.append(
diff --git a/lib/lp/code/model/tests/test_branch.py b/lib/lp/code/model/tests/test_branch.py
index d31581b..6ea7f28 100644
--- a/lib/lp/code/model/tests/test_branch.py
+++ b/lib/lp/code/model/tests/test_branch.py
@@ -60,6 +60,7 @@ from lp.code.interfaces.branchlookup import IBranchLookup
 from lp.code.interfaces.branchmergeproposal import (
     BRANCH_MERGE_PROPOSAL_FINAL_STATES as FINAL_STATES,
 )
+from lp.code.interfaces.branchmergeproposal import IBranchMergeProposalGetter
 from lp.code.interfaces.branchnamespace import (
     IBranchNamespacePolicy,
     IBranchNamespaceSet,
@@ -87,7 +88,6 @@ from lp.code.model.branchjob import (
     BranchScanJob,
     ReclaimBranchSpaceJob,
 )
-from lp.code.model.branchmergeproposal import BranchMergeProposal
 from lp.code.model.branchrevision import BranchRevision
 from lp.code.model.codereviewcomment import CodeReviewComment
 from lp.code.model.revision import Revision
@@ -110,7 +110,6 @@ from lp.registry.tests.test_accesspolicy import get_policies_for_artifact
 from lp.services.config import config
 from lp.services.database.constants import UTC_NOW
 from lp.services.database.interfaces import IStore
-from lp.services.database.sqlobject import SQLObjectNotFound
 from lp.services.features.testing import FeatureFixture
 from lp.services.job.interfaces.job import JobStatus
 from lp.services.job.runner import JobRunner
@@ -1701,20 +1700,24 @@ class TestBranchDeletionConsequences(TestCase):
         """Merge proposal source branches can be deleted with break_links."""
         merge_proposal1, merge_proposal2 = self.makeMergeProposals()
         merge_proposal1_id = merge_proposal1.id
-        BranchMergeProposal.get(merge_proposal1_id)
+        getUtility(IBranchMergeProposalGetter).get(merge_proposal1_id)
         self.branch.destroySelf(break_references=True)
         self.assertRaises(
-            SQLObjectNotFound, BranchMergeProposal.get, merge_proposal1_id
+            NotFoundError,
+            getUtility(IBranchMergeProposalGetter).get,
+            merge_proposal1_id,
         )
 
     def test_deleteMergeProposalTarget(self):
         """Merge proposal target branches can be deleted with break_links."""
         merge_proposal1, merge_proposal2 = self.makeMergeProposals()
         merge_proposal1_id = merge_proposal1.id
-        BranchMergeProposal.get(merge_proposal1_id)
+        getUtility(IBranchMergeProposalGetter).get(merge_proposal1_id)
         merge_proposal1.target_branch.destroySelf(break_references=True)
         self.assertRaises(
-            SQLObjectNotFound, BranchMergeProposal.get, merge_proposal1_id
+            NotFoundError,
+            getUtility(IBranchMergeProposalGetter).get,
+            merge_proposal1_id,
         )
 
     def test_deleteMergeProposalDependent(self):
diff --git a/lib/lp/code/model/tests/test_gitrepository.py b/lib/lp/code/model/tests/test_gitrepository.py
index f74776f..057c80a 100644
--- a/lib/lp/code/model/tests/test_gitrepository.py
+++ b/lib/lp/code/model/tests/test_gitrepository.py
@@ -76,6 +76,7 @@ from lp.code.event.git import GitRefsUpdatedEvent
 from lp.code.interfaces.branchmergeproposal import (
     BRANCH_MERGE_PROPOSAL_FINAL_STATES as FINAL_STATES,
 )
+from lp.code.interfaces.branchmergeproposal import IBranchMergeProposalGetter
 from lp.code.interfaces.cibuild import (
     CI_WEBHOOKS_FEATURE_FLAG,
     ICIBuild,
@@ -103,7 +104,6 @@ from lp.code.interfaces.revisionstatus import (
     IRevisionStatusArtifactSet,
     IRevisionStatusReportSet,
 )
-from lp.code.model.branchmergeproposal import BranchMergeProposal
 from lp.code.model.branchmergeproposaljob import (
     BranchMergeProposalJob,
     BranchMergeProposalJobType,
@@ -156,7 +156,6 @@ from lp.services.config import config
 from lp.services.database.constants import UTC_NOW
 from lp.services.database.interfaces import IStore
 from lp.services.database.sqlbase import get_transaction_timestamp
-from lp.services.database.sqlobject import SQLObjectNotFound
 from lp.services.features.testing import FeatureFixture
 from lp.services.identity.interfaces.account import AccountStatus
 from lp.services.job.interfaces.job import JobStatus
@@ -1553,10 +1552,12 @@ class TestGitRepositoryDeletionConsequences(TestCaseWithFactory):
         # break_references.
         merge_proposal1, merge_proposal2 = self.makeMergeProposals()
         merge_proposal1_id = merge_proposal1.id
-        BranchMergeProposal.get(merge_proposal1_id)
+        getUtility(IBranchMergeProposalGetter).get(merge_proposal1_id)
         self.repository.destroySelf(break_references=True)
         self.assertRaises(
-            SQLObjectNotFound, BranchMergeProposal.get, merge_proposal1_id
+            NotFoundError,
+            getUtility(IBranchMergeProposalGetter).get,
+            merge_proposal1_id,
         )
 
     def test_delete_merge_proposal_target(self):
@@ -1564,12 +1565,14 @@ class TestGitRepositoryDeletionConsequences(TestCaseWithFactory):
         # break_references.
         merge_proposal1, merge_proposal2 = self.makeMergeProposals()
         merge_proposal1_id = merge_proposal1.id
-        BranchMergeProposal.get(merge_proposal1_id)
+        getUtility(IBranchMergeProposalGetter).get(merge_proposal1_id)
         merge_proposal1.target_git_repository.destroySelf(
             break_references=True
         )
         self.assertRaises(
-            SQLObjectNotFound, BranchMergeProposal.get, merge_proposal1_id
+            NotFoundError,
+            getUtility(IBranchMergeProposalGetter).get,
+            merge_proposal1_id,
         )
 
     def test_delete_merge_proposal_prerequisite(self):
@@ -1728,7 +1731,9 @@ class TestGitRepositoryDeletionConsequences(TestCaseWithFactory):
             merge_proposal, "blah", merge_proposal.deleteProposal
         )()
         self.assertRaises(
-            SQLObjectNotFound, BranchMergeProposal.get, merge_proposal_id
+            NotFoundError,
+            getUtility(IBranchMergeProposalGetter).get,
+            merge_proposal_id,
         )
 
     def test_DeleteCodeImport(self):