← Back to team overview

launchpad-reviewers team mailing list archive

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

 

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

Commit message:
Convert SourcePackageRelease to Storm

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/446938
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-sourcepackagerelease into launchpad:master.
diff --git a/lib/lp/archivepublisher/model/ftparchive.py b/lib/lp/archivepublisher/model/ftparchive.py
index 2745cb1..14cd8e2 100644
--- a/lib/lp/archivepublisher/model/ftparchive.py
+++ b/lib/lp/archivepublisher/model/ftparchive.py
@@ -311,7 +311,7 @@ class FTPArchiveHandler:
             Join(
                 SourcePackageName,
                 SourcePackageName.id
-                == SourcePackageRelease.sourcepackagenameID,
+                == SourcePackageRelease.sourcepackagename_id,
             ),
         )
 
diff --git a/lib/lp/archiveuploader/tests/test_uploadprocessor.py b/lib/lp/archiveuploader/tests/test_uploadprocessor.py
index 665bc0b..2778c32 100644
--- a/lib/lp/archiveuploader/tests/test_uploadprocessor.py
+++ b/lib/lp/archiveuploader/tests/test_uploadprocessor.py
@@ -1097,8 +1097,10 @@ class TestUploadProcessor(StatsMixin, TestUploadProcessorBase):
 
         # Find the sourcepackagerelease and check its component.
         foocomm_name = SourcePackageName.selectOneBy(name="foocomm")
-        foocomm_spr = SourcePackageRelease.selectOneBy(
-            sourcepackagename=foocomm_name
+        foocomm_spr = (
+            IStore(SourcePackageRelease)
+            .find(SourcePackageRelease, sourcepackagename=foocomm_name)
+            .one()
         )
         self.assertEqual(foocomm_spr.component.name, "partner")
 
diff --git a/lib/lp/bugs/browser/bugtask.py b/lib/lp/bugs/browser/bugtask.py
index ad3a7a2..8d999cb 100644
--- a/lib/lp/bugs/browser/bugtask.py
+++ b/lib/lp/bugs/browser/bugtask.py
@@ -2075,7 +2075,7 @@ class BugTasksTableView(LaunchpadView):
         )
         ids = set()
         for release_person_ids in map(
-            attrgetter("creatorID", "maintainerID"),
+            attrgetter("creator_id", "maintainer_id"),
             self.target_releases.values(),
         ):
             ids.update(release_person_ids)
diff --git a/lib/lp/registry/doc/distribution.rst b/lib/lp/registry/doc/distribution.rst
index 74c98f9..e618751 100644
--- a/lib/lp/registry/doc/distribution.rst
+++ b/lib/lp/registry/doc/distribution.rst
@@ -89,9 +89,12 @@ have a SourcePackageName object for it.
     >>> IDistributionSourcePackage.providedBy(evo_ubuntu)
     True
 
+    >>> from lp.services.database.interfaces import IStore
     >>> from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
-    >>> sourcepackagerelease = SourcePackageRelease.selectOneBy(
-    ...     sourcepackagenameID=evo.id, version="1.0"
+    >>> sourcepackagerelease = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(SourcePackageRelease, sourcepackagename=evo, version="1.0")
+    ...     .one()
     ... )
     >>> print(sourcepackagerelease.name)
     evolution
diff --git a/lib/lp/registry/model/distributionsourcepackage.py b/lib/lp/registry/model/distributionsourcepackage.py
index 42a452d..e7dc893 100644
--- a/lib/lp/registry/model/distributionsourcepackage.py
+++ b/lib/lp/registry/model/distributionsourcepackage.py
@@ -334,7 +334,7 @@ class DistributionSourcePackage(
             SourcePackageRelease.upload_archive == Archive.id,
             # Next, the joins for the ordering by soyuz karma of the
             # SPR creator.
-            KarmaTotalCache.person == SourcePackageRelease.creatorID,
+            KarmaTotalCache.person == SourcePackageRelease.creator_id,
             *extra_args,
         )
 
@@ -435,7 +435,10 @@ class DistributionSourcePackage(
         def decorate(spr_ids):
             # Find the SPPHs for each SPR in our result.
             load(SourcePackageRelease, spr_ids)
-            sprs = [SourcePackageRelease.get(spr_id) for spr_id in spr_ids]
+            sprs = [
+                IStore(SourcePackageRelease).get(SourcePackageRelease, spr_id)
+                for spr_id in spr_ids
+            ]
             pubs = DistributionSourcePackageRelease.getPublishingHistories(
                 self.distribution, sprs
             )
diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py
index e801a05..3e70f64 100644
--- a/lib/lp/registry/model/distroseries.py
+++ b/lib/lp/registry/model/distroseries.py
@@ -1368,7 +1368,7 @@ class DistroSeries(
         clauses = [
             PackageUploadSource.sourcepackagerelease
             == SourcePackageRelease.id,
-            SourcePackageRelease.sourcepackagenameID == SourcePackageName.id,
+            SourcePackageRelease.sourcepackagename_id == SourcePackageName.id,
             PackageUploadSource.packageupload == Column("id", RelevantUpload),
         ]
 
diff --git a/lib/lp/registry/model/distroseriesdifference.py b/lib/lp/registry/model/distroseriesdifference.py
index 23602af..1f85478 100644
--- a/lib/lp/registry/model/distroseriesdifference.py
+++ b/lib/lp/registry/model/distroseriesdifference.py
@@ -334,7 +334,7 @@ def eager_load_dsds(dsds):
     person_ids = set().union(
         (dsdc.message.owner_id for dsdc in latest_comments),
         (sprb.requester_id for sprb in sprbs),
-        (spr.creatorID for spr in sprs),
+        (spr.creator_id for spr in sprs),
         (spr.signing_key_owner_id for spr in sprs),
     )
     uploaders = getUtility(IPersonSet).getPrecachedPersonsFromIDs(
@@ -505,8 +505,8 @@ class DistroSeriesDifference(StormBase):
                 SPPH.distroseries == distro_series,
                 SPPH.sourcepackagerelease_id == SPR.id,
                 SPPH.status.is_in(active_publishing_status),
-                SPR.creatorID == TP.personID,
-                SPR.sourcepackagenameID == DSD.source_package_name_id,
+                SPR.creator_id == TP.personID,
+                SPR.sourcepackagename_id == DSD.source_package_name_id,
                 TP.teamID.is_in(person.id for person in changed_by),
             )
             differences_changed_by = store.find(
diff --git a/lib/lp/registry/model/person.py b/lib/lp/registry/model/person.py
index d53f091..e0b5d88 100644
--- a/lib/lp/registry/model/person.py
+++ b/lib/lp/registry/model/person.py
@@ -3409,13 +3409,13 @@ class Person(
                         ),
                         order_by=[
                             spph.distroseries_id,
-                            SourcePackageRelease.sourcepackagenameID,
+                            SourcePackageRelease.sourcepackagename_id,
                             Desc(spph.datecreated),
                             Desc(spph.id),
                         ],
                         distinct=(
                             spph.distroseries_id,
-                            SourcePackageRelease.sourcepackagenameID,
+                            SourcePackageRelease.sourcepackagename_id,
                         ),
                     )
                 ),
diff --git a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
index b12fede..4038633 100644
--- a/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
+++ b/lib/lp/registry/scripts/tests/test_populate_distroseriesdiff.py
@@ -113,7 +113,7 @@ class TestFindLatestSourcePackageReleases(TestCaseWithFactory, FactoryHelper):
             to return for `spph`.
         """
         spr = spph.sourcepackagerelease
-        return (spr.sourcepackagenameID, spr.id, spr.version)
+        return (spr.sourcepackagename_id, spr.id, spr.version)
 
     def test_baseline(self):
         distroseries = self.factory.makeDistroSeries()
@@ -327,7 +327,7 @@ class TestFindDifferences(TestCaseWithFactory, FactoryHelper):
         self.assertContentEqual(
             [
                 (
-                    spph.sourcepackagerelease.sourcepackagenameID,
+                    spph.sourcepackagerelease.sourcepackagename_id,
                     None,
                     spph.sourcepackagerelease.version,
                 )
@@ -343,7 +343,7 @@ class TestFindDifferences(TestCaseWithFactory, FactoryHelper):
         self.assertContentEqual(
             [
                 (
-                    spph.sourcepackagerelease.sourcepackagenameID,
+                    spph.sourcepackagerelease.sourcepackagename_id,
                     spph.sourcepackagerelease.version,
                     None,
                 )
@@ -361,12 +361,12 @@ class TestFindDifferences(TestCaseWithFactory, FactoryHelper):
         self.assertContentEqual(
             [
                 (
-                    parent_spph.sourcepackagerelease.sourcepackagenameID,
+                    parent_spph.sourcepackagerelease.sourcepackagename_id,
                     None,
                     parent_spph.sourcepackagerelease.version,
                 ),
                 (
-                    derived_spph.sourcepackagerelease.sourcepackagenameID,
+                    derived_spph.sourcepackagerelease.sourcepackagename_id,
                     derived_spph.sourcepackagerelease.version,
                     None,
                 ),
@@ -395,7 +395,7 @@ class TestFindDifferences(TestCaseWithFactory, FactoryHelper):
         self.assertContentEqual(
             [
                 (
-                    parent_spph.sourcepackagerelease.sourcepackagenameID,
+                    parent_spph.sourcepackagerelease.sourcepackagename_id,
                     derived_spph.sourcepackagerelease.version,
                     parent_spph.sourcepackagerelease.version,
                 )
@@ -427,7 +427,7 @@ class TestFindDifferences(TestCaseWithFactory, FactoryHelper):
         self.assertContentEqual(
             [
                 (
-                    parent_spph.sourcepackagerelease.sourcepackagenameID,
+                    parent_spph.sourcepackagerelease.sourcepackagename_id,
                     newer_spr.version,
                     shared_spr.version,
                 )
diff --git a/lib/lp/scripts/garbo.py b/lib/lp/scripts/garbo.py
index 7781da4..032dd17 100644
--- a/lib/lp/scripts/garbo.py
+++ b/lib/lp/scripts/garbo.py
@@ -626,7 +626,7 @@ class PopulateLatestPersonSourcePackageReleaseCache(TunableLoop):
                 spph,
                 And(
                     spph.sourcepackagerelease_id == SourcePackageRelease.id,
-                    spph.archive_id == SourcePackageRelease.upload_archiveID,
+                    spph.archive_id == SourcePackageRelease.upload_archive_id,
                 ),
             ),
             Join(Archive, Archive.id == spph.archive_id),
@@ -636,12 +636,12 @@ class PopulateLatestPersonSourcePackageReleaseCache(TunableLoop):
             .find(
                 (
                     SourcePackageRelease.id,
-                    SourcePackageRelease.creatorID,
-                    SourcePackageRelease.maintainerID,
-                    SourcePackageRelease.upload_archiveID,
+                    SourcePackageRelease.creator_id,
+                    SourcePackageRelease.maintainer_id,
+                    SourcePackageRelease.upload_archive_id,
                     Archive.purpose,
-                    SourcePackageRelease.upload_distroseriesID,
-                    SourcePackageRelease.sourcepackagenameID,
+                    SourcePackageRelease.upload_distroseries_id,
+                    SourcePackageRelease.sourcepackagename_id,
                     SourcePackageRelease.dateuploaded,
                     spph.id,
                 ),
@@ -2199,7 +2199,7 @@ class BinaryPackagePublishingHistorySPNPopulator(BulkPruner):
             BulkUpdate(
                 {
                     BPPH.sourcepackagename_id: (
-                        SourcePackageRelease.sourcepackagenameID
+                        SourcePackageRelease.sourcepackagename_id
                     )
                 },
                 table=BPPH,
diff --git a/lib/lp/soyuz/adapters/archivesourcepublication.py b/lib/lp/soyuz/adapters/archivesourcepublication.py
index d9d106c..4bcf1e4 100644
--- a/lib/lp/soyuz/adapters/archivesourcepublication.py
+++ b/lib/lp/soyuz/adapters/archivesourcepublication.py
@@ -118,7 +118,7 @@ class ArchiveSourcePublications:
         # batch load the used source package names.
         spn_ids = set()
         for spph in self._source_publications:
-            spn_ids.add(spph.sourcepackagerelease.sourcepackagenameID)
+            spn_ids.add(spph.sourcepackagerelease.sourcepackagename_id)
         list(
             IStore(SourcePackageName).find(
                 SourcePackageName, SourcePackageName.id.is_in(spn_ids)
diff --git a/lib/lp/soyuz/browser/queue.py b/lib/lp/soyuz/browser/queue.py
index d187d9f..bcae209 100644
--- a/lib/lp/soyuz/browser/queue.py
+++ b/lib/lp/soyuz/browser/queue.py
@@ -177,7 +177,7 @@ class QueueItemsView(LaunchpadView):
         """
         sprs = [spr for spr in source_package_releases if spr is not None]
         return getUtility(IPackagesetSet).getForPackages(
-            self.context, {spr.sourcepackagenameID for spr in sprs}
+            self.context, {spr.sourcepackagename_id for spr in sprs}
         )
 
     def loadPackageCopyJobs(self, uploads):
@@ -548,7 +548,7 @@ class CompletePackageUpload:
         if self.contains_source:
             self.sourcepackagerelease = self.sources[0].sourcepackagerelease
             self.package_sets = package_sets.get(
-                self.sourcepackagerelease.sourcepackagenameID, []
+                self.sourcepackagerelease.sourcepackagename_id, []
             )
         else:
             self.package_sets = []
diff --git a/lib/lp/soyuz/doc/gina-multiple-arch.rst b/lib/lp/soyuz/doc/gina-multiple-arch.rst
index 3d16759..36d9045 100644
--- a/lib/lp/soyuz/doc/gina-multiple-arch.rst
+++ b/lib/lp/soyuz/doc/gina-multiple-arch.rst
@@ -17,7 +17,9 @@ Get the current counts of stuff in the database:
     >>> SSPPH = SourcePackagePublishingHistory
     >>> SBPPH = BinaryPackagePublishingHistory
 
-    >>> orig_spr_count = SourcePackageRelease.select().count()
+    >>> orig_spr_count = (
+    ...     IStore(SourcePackageRelease).find(SourcePackageRelease).count()
+    ... )
     >>> orig_sspph_count = IStore(SSPPH).find(SSPPH).count()
     >>> orig_person_count = Person.select().count()
     >>> orig_tp_count = TeamParticipation.select().count()
@@ -128,7 +130,10 @@ Check the quantities that were returned. We have:
 We have two source packages, and we're only really publishing into
 breezy:
 
-    >>> SourcePackageRelease.select().count() - orig_spr_count
+    >>> (
+    ...     IStore(SourcePackageRelease).find(SourcePackageRelease).count()
+    ...     - orig_spr_count
+    ... )
     2
     >>> print(IStore(SSPPH).find(SSPPH).count() - orig_sspph_count)
     2
@@ -162,8 +167,14 @@ Check that the source package was correctly imported:
     >>> from lp.soyuz.model.binarypackagename import BinaryPackageName
     >>> from lp.registry.model.sourcepackagename import SourcePackageName
     >>> n = SourcePackageName.selectOneBy(name="ekg")
-    >>> ekg = SourcePackageRelease.selectOneBy(
-    ...     sourcepackagenameID=n.id, version="1:1.5-4ubuntu1.2"
+    >>> ekg = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(
+    ...         SourcePackageRelease,
+    ...         sourcepackagename=n,
+    ...         version="1:1.5-4ubuntu1.2",
+    ...     )
+    ...     .one()
     ... )
     >>> print(ekg.section.name)
     net
diff --git a/lib/lp/soyuz/doc/gina.rst b/lib/lp/soyuz/doc/gina.rst
index c225f5c..bc17db6 100644
--- a/lib/lp/soyuz/doc/gina.rst
+++ b/lib/lp/soyuz/doc/gina.rst
@@ -24,7 +24,9 @@ Get the current counts of stuff in the database:
     >>> SSPPH = SourcePackagePublishingHistory
     >>> SBPPH = BinaryPackagePublishingHistory
 
-    >>> orig_spr_count = SourcePackageRelease.select().count()
+    >>> orig_spr_count = (
+    ...     IStore(SourcePackageRelease).find(SourcePackageRelease).count()
+    ... )
     >>> orig_sspph_count = IStore(SSPPH).find(SSPPH).count()
     >>> orig_person_count = Person.select().count()
     >>> orig_tp_count = TeamParticipation.select().count()
@@ -230,7 +232,9 @@ forcefully (ubuntu-meta).
 
     >>> hc + bc
     16
-    >>> count = SourcePackageRelease.select().count()
+    >>> count = (
+    ...     IStore(SourcePackageRelease).find(SourcePackageRelease).count()
+    ... )
     >>> count - orig_spr_count
     17
 
@@ -238,8 +242,14 @@ Check that x11proto-damage has its Build-Depends-Indep value correctly set:
 
     >>> from lp.registry.model.sourcepackagename import SourcePackageName
     >>> n = SourcePackageName.selectOneBy(name="x11proto-damage")
-    >>> x11p = SourcePackageRelease.selectOneBy(
-    ...     sourcepackagenameID=n.id, version="6.8.99.7-2"
+    >>> x11p = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(
+    ...         SourcePackageRelease,
+    ...         sourcepackagename=n,
+    ...         version="6.8.99.7-2",
+    ...     )
+    ...     .one()
     ... )
 
     >>> print(x11p.builddependsindep)
@@ -289,7 +299,11 @@ Check that the dsc on the libcap package is correct, and that we
 only imported one:
 
     >>> n = SourcePackageName.selectOneBy(name="libcap")
-    >>> cap = SourcePackageRelease.selectOneBy(sourcepackagenameID=n.id)
+    >>> cap = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(SourcePackageRelease, sourcepackagename=n)
+    ...     .one()
+    ... )
     >>> print(cap.dsc)
     -----BEGIN PGP SIGNED MESSAGE-----
     Hash: SHA1
@@ -321,8 +335,10 @@ only imported one:
 Test ubuntu-meta in breezy, which was forcefully imported.
 
     >>> n = SourcePackageName.selectOneBy(name="ubuntu-meta")
-    >>> um = SourcePackageRelease.selectOneBy(
-    ...     sourcepackagenameID=n.id, version="0.80"
+    >>> um = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(SourcePackageRelease, sourcepackagename=n, version="0.80")
+    ...     .one()
     ... )
     >>> print(
     ...     um.section.name,
@@ -351,7 +367,11 @@ Check that the section on the python-pam package is correct, and that we
 only imported one:
 
     >>> n = SourcePackageName.selectOneBy(name="python-pam")
-    >>> pp = SourcePackageRelease.selectOneBy(sourcepackagenameID=n.id)
+    >>> pp = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(SourcePackageRelease, sourcepackagename=n)
+    ...     .one()
+    ... )
     >>> print(pp.component.name)
     main
 
@@ -364,7 +384,11 @@ this is cut up correctly:
 Make sure that we only imported one db1-compat source package.
 
     >>> n = SourcePackageName.selectOneBy(name="db1-compat")
-    >>> db1 = SourcePackageRelease.selectOneBy(sourcepackagenameID=n.id)
+    >>> db1 = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(SourcePackageRelease, sourcepackagename=n)
+    ...     .one()
+    ... )
     >>> print(db1.section.name)
     libs
 
@@ -660,7 +684,10 @@ run.
 Nothing should happen to most of our data -- no counts should have
 changed, etc.
 
-    >>> SourcePackageRelease.select().count() - orig_spr_count
+    >>> (
+    ...     IStore(SourcePackageRelease).find(SourcePackageRelease).count()
+    ...     - orig_spr_count
+    ... )
     17
     >>> print(Person.select().count() - orig_person_count)
     13
@@ -712,8 +739,10 @@ package -- that's what overrides actually do.
     >>> print(ed_pub.priority)
     Extra
     >>> n = SourcePackageName.selectOneBy(name="archive-copier")
-    >>> ac = SourcePackageRelease.selectOneBy(
-    ...     sourcepackagenameID=n.id, version="0.3.6"
+    >>> ac = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(SourcePackageRelease, sourcepackagename=n, version="0.3.6")
+    ...     .one()
     ... )
     >>> ac_pub = (
     ...     IStore(SSPPH)
diff --git a/lib/lp/soyuz/doc/package-meta-classes.rst b/lib/lp/soyuz/doc/package-meta-classes.rst
index e741141..62cc13b 100644
--- a/lib/lp/soyuz/doc/package-meta-classes.rst
+++ b/lib/lp/soyuz/doc/package-meta-classes.rst
@@ -6,6 +6,7 @@ our Database Model for packages in a intuitive manner, they are:
 
     >>> from lp.registry.model.distribution import Distribution
     >>> from lp.registry.model.sourcepackagename import SourcePackageName
+    >>> from lp.services.database.interfaces import IStore
     >>> from lp.soyuz.model.distributionsourcepackagerelease import (
     ...     DistributionSourcePackageRelease,
     ... )
@@ -29,8 +30,14 @@ Combining Distribution and SourcePackageRelease:
     >>> print(src_name.name)
     pmount
 
-    >>> sourcepackagerelease = SourcePackageRelease.selectOneBy(
-    ...     sourcepackagenameID=src_name.id, version="0.1-1"
+    >>> sourcepackagerelease = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(
+    ...         SourcePackageRelease,
+    ...         sourcepackagename=src_name,
+    ...         version="0.1-1",
+    ...     )
+    ...     .one()
     ... )
     >>> print(sourcepackagerelease.name)
     pmount
diff --git a/lib/lp/soyuz/doc/sourcepackagerelease.rst b/lib/lp/soyuz/doc/sourcepackagerelease.rst
index eca456e..f68e146 100644
--- a/lib/lp/soyuz/doc/sourcepackagerelease.rst
+++ b/lib/lp/soyuz/doc/sourcepackagerelease.rst
@@ -16,8 +16,9 @@ Basic attributes
 
 Let's get one from the database:
 
+    >>> from lp.services.database.interfaces import IStore
     >>> from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
-    >>> spr = SourcePackageRelease.get(20)
+    >>> spr = IStore(SourcePackageRelease).get(SourcePackageRelease, 20)
     >>> print(spr.name)
     pmount
     >>> print(spr.version)
@@ -88,7 +89,9 @@ All the builds returned are for non-PPA archives:
 
 Check that the uploaded changesfile works:
 
-    >>> commercial = SourcePackageRelease.get(36)
+    >>> commercial = IStore(SourcePackageRelease).get(
+    ...     SourcePackageRelease, 36
+    ... )
     >>> commercial.upload_changesfile.http_url
     'http://.../commercialpackage_1.0-1_source.changes'
 
@@ -214,7 +217,7 @@ Throw away the DB changes:
 
 Let's get a sample SourcePackageRelease:
 
-    >>> spr_test = SourcePackageRelease.get(20)
+    >>> spr_test = IStore(SourcePackageRelease).get(SourcePackageRelease, 20)
     >>> print(spr_test.name)
     pmount
 
@@ -226,7 +229,7 @@ The size of a source package can be obtained via the getPackageSize() method.
 It returns the sum of the size of all files comprising the source package (in
 kilo-bytes).
 
-    >>> spr = SourcePackageRelease.get(14)
+    >>> spr = IStore(SourcePackageRelease).get(SourcePackageRelease, 14)
     >>> print(spr.name)
     mozilla-firefox
     >>> spr.getPackageSize()
@@ -236,8 +239,14 @@ Verify that empty packages have a size of zero.
 
     >>> from lp.registry.model.sourcepackagename import SourcePackageName
     >>> linux_src = SourcePackageName.selectOneBy(name="linux-source-2.6.15")
-    >>> spr = SourcePackageRelease.selectOneBy(
-    ...     sourcepackagename=linux_src, version="2.6.15.3"
+    >>> spr = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(
+    ...         SourcePackageRelease,
+    ...         sourcepackagename=linux_src,
+    ...         version="2.6.15.3",
+    ...     )
+    ...     .one()
     ... )
     >>> spr.getPackageSize()
     0.0
diff --git a/lib/lp/soyuz/doc/soyuz-upload.rst b/lib/lp/soyuz/doc/soyuz-upload.rst
index f6027d6..9413550 100644
--- a/lib/lp/soyuz/doc/soyuz-upload.rst
+++ b/lib/lp/soyuz/doc/soyuz-upload.rst
@@ -326,11 +326,16 @@ Let's check if packages were uploaded correctly.
 
     >>> from operator import attrgetter
     >>> from lp.registry.model.sourcepackagename import SourcePackageName
+    >>> from lp.services.database.interfaces import IStore
     >>> from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
     >>> spn = SourcePackageName.selectOneBy(name="drdsl")
     >>> print(spn.name)
     drdsl
-    >>> spr = SourcePackageRelease.selectOneBy(sourcepackagenameID=spn.id)
+    >>> spr = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(SourcePackageRelease, sourcepackagename=spn)
+    ...     .one()
+    ... )
     >>> print(spr.title)
     drdsl - 1.2.0-0ubuntu1
     >>> print(spr.name)
@@ -362,7 +367,11 @@ Same thing for etherwake:
     >>> spn = SourcePackageName.selectOneBy(name="etherwake")
     >>> print(spn.name)
     etherwake
-    >>> spr = SourcePackageRelease.selectOneBy(sourcepackagenameID=spn.id)
+    >>> spr = (
+    ...     IStore(SourcePackageRelease)
+    ...     .find(SourcePackageRelease, sourcepackagename=spn)
+    ...     .one()
+    ... )
     >>> print(spr.title)
     etherwake - 1.08-1
     >>> print(spr.name)
@@ -422,12 +431,15 @@ Also check the upload folders contain all the files we uploaded.
 Now let's see if all of the valid uploads are in the Upload queue marked
 as NEW and RELEASE.
 
-    >>> from lp.services.database.interfaces import IStore
     >>> from lp.soyuz.model.queue import PackageUploadSource
     >>> for name in package_names:
     ...     print(name)
     ...     spn = SourcePackageName.selectOneBy(name=name)
-    ...     spr = SourcePackageRelease.selectOneBy(sourcepackagenameID=spn.id)
+    ...     spr = (
+    ...         IStore(SourcePackageRelease)
+    ...         .find(SourcePackageRelease, sourcepackagename=spn)
+    ...         .one()
+    ...     )
     ...     us = (
     ...         IStore(PackageUploadSource)
     ...         .find(PackageUploadSource, sourcepackagerelease=spr)
@@ -497,7 +509,11 @@ These packages must now be in the publishing history. Let's check it.
     >>> package_names.sort()
     >>> for name in package_names:
     ...     spn = SourcePackageName.selectOneBy(name=name)
-    ...     spr = SourcePackageRelease.selectOneBy(sourcepackagenameID=spn.id)
+    ...     spr = (
+    ...         IStore(SourcePackageRelease)
+    ...         .find(SourcePackageRelease, sourcepackagename=spn)
+    ...         .one()
+    ...     )
     ...     sspph = IStore(SSPPH).find(SSPPH, sourcepackagerelease=spr).one()
     ...     if sspph:
     ...         print(name, sspph.status.title)
diff --git a/lib/lp/soyuz/interfaces/sourcepackagerelease.py b/lib/lp/soyuz/interfaces/sourcepackagerelease.py
index a6f1c64..674fda9 100644
--- a/lib/lp/soyuz/interfaces/sourcepackagerelease.py
+++ b/lib/lp/soyuz/interfaces/sourcepackagerelease.py
@@ -19,9 +19,9 @@ class ISourcePackageRelease(Interface):
     """A source package release, e.g. apache-utils 2.0.48-3"""
 
     id = Attribute("SourcePackageRelease identifier")
-    creatorID = Attribute("DB ID of creator")
+    creator_id = Attribute("DB ID of creator")
     creator = Attribute("Person that created this release")
-    maintainerID = Attribute("DB ID of the maintainer")
+    maintainer_id = Attribute("DB ID of the maintainer")
     maintainer = Attribute(
         "The person in general responsible for this " "release"
     )
@@ -112,7 +112,7 @@ class ISourcePackageRelease(Interface):
         "IBinaryPackageFile entries for this " "sourcepackagerelease"
     )
     sourcepackagename = Attribute("SourcePackageName table reference")
-    sourcepackagenameID = Attribute("SourcePackageName id.")
+    sourcepackagename_id = Attribute("SourcePackageName id.")
     upload_distroseries = Attribute(
         "The distroseries in which this package "
         "was first uploaded in Launchpad"
diff --git a/lib/lp/soyuz/model/archive.py b/lib/lp/soyuz/model/archive.py
index 72264d4..18123ac 100644
--- a/lib/lp/soyuz/model/archive.py
+++ b/lib/lp/soyuz/model/archive.py
@@ -692,7 +692,7 @@ class Archive(SQLBase):
             # attrgetter).
             spn_ids = set(
                 map(
-                    attrgetter("sourcepackagerelease.sourcepackagenameID"),
+                    attrgetter("sourcepackagerelease.sourcepackagename_id"),
                     rows,
                 )
             )
@@ -853,7 +853,7 @@ class Archive(SQLBase):
                     SourcePackageRelease, SourcePackageRelease.id.is_in(ids)
                 )
             )
-            ids = set(map(attrgetter("creatorID"), releases))
+            ids = set(map(attrgetter("creator_id"), releases))
             ids.discard(None)
             if ids:
                 list(getUtility(IPersonSet).getPrecachedPersonsFromIDs(ids))
@@ -1116,7 +1116,7 @@ class Archive(SQLBase):
             sprs = load_related(
                 SourcePackageRelease, bpbs, ["source_package_release_id"]
             )
-            load_related(SourcePackageName, sprs, ["sourcepackagenameID"])
+            load_related(SourcePackageName, sprs, ["sourcepackagename_id"])
             load_related(Component, bpphs, ["component_id"])
             load_related(Section, bpphs, ["section_id"])
             dases = load_related(
diff --git a/lib/lp/soyuz/model/binarypackagebuild.py b/lib/lp/soyuz/model/binarypackagebuild.py
index b71a38d..f17edcc 100644
--- a/lib/lp/soyuz/model/binarypackagebuild.py
+++ b/lib/lp/soyuz/model/binarypackagebuild.py
@@ -1299,7 +1299,7 @@ class BinaryPackageBuildSet(SpecificBuildFarmJobSourceMixin):
             Join(
                 SourcePackageName,
                 SourcePackageName.id
-                == SourcePackageRelease.sourcepackagenameID,
+                == SourcePackageRelease.sourcepackagename_id,
             ),
             LeftJoin(
                 LibraryFileAlias,
diff --git a/lib/lp/soyuz/model/distributionsourcepackagecache.py b/lib/lp/soyuz/model/distributionsourcepackagecache.py
index 29c3481..08c7253 100644
--- a/lib/lp/soyuz/model/distributionsourcepackagecache.py
+++ b/lib/lp/soyuz/model/distributionsourcepackagecache.py
@@ -169,7 +169,7 @@ class DistributionSourcePackageCache(StormBase):
             IStore(SourcePackageRelease)
             .find(
                 (
-                    SourcePackageRelease.sourcepackagenameID,
+                    SourcePackageRelease.sourcepackagename_id,
                     SourcePackageRelease.id,
                     SourcePackageRelease.version,
                 ),
diff --git a/lib/lp/soyuz/model/packagediff.py b/lib/lp/soyuz/model/packagediff.py
index 6e84152..47ed2b2 100644
--- a/lib/lp/soyuz/model/packagediff.py
+++ b/lib/lp/soyuz/model/packagediff.py
@@ -353,7 +353,7 @@ class PackageDiffSet:
                     (pd.from_source_id, pd.to_source_id) for pd in rows
                 ),
             )
-            archives = load(Archive, (spr.upload_archiveID for spr in sprs))
+            archives = load(Archive, (spr.upload_archive_id for spr in sprs))
             load(Distribution, (a.distributionID for a in archives))
 
         if preload_for_display:
diff --git a/lib/lp/soyuz/model/publishing.py b/lib/lp/soyuz/model/publishing.py
index 470032d..0d26351 100644
--- a/lib/lp/soyuz/model/publishing.py
+++ b/lib/lp/soyuz/model/publishing.py
@@ -2082,7 +2082,9 @@ class PublishingSet:
             sprs = bulk.load_related(
                 SourcePackageRelease, spphs, ["sourcepackagerelease_id"]
             )
-            bulk.load_related(SourcePackageName, sprs, ["sourcepackagenameID"])
+            bulk.load_related(
+                SourcePackageName, sprs, ["sourcepackagename_id"]
+            )
             spr_ids = set(map(attrgetter("id"), sprs))
             sprfs = list(
                 IStore(SourcePackageReleaseFile)
@@ -2157,7 +2159,9 @@ class PublishingSet:
                 LibraryFileAlias, bpfs, ["libraryfile_id"]
             )
             bulk.load_related(LibraryFileContent, lfas, ["contentID"])
-            bulk.load_related(SourcePackageName, sprs, ["sourcepackagenameID"])
+            bulk.load_related(
+                SourcePackageName, sprs, ["sourcepackagename_id"]
+            )
             bulk.load_related(
                 BinaryPackageName, bprs, ["binarypackagename_id"]
             )
@@ -2186,8 +2190,8 @@ class PublishingSet:
             PackageUpload.id == PackageUploadSource.packageupload_id,
             PackageUpload.status == PackageUploadStatus.DONE,
             PackageUpload.distroseries
-            == SourcePackageRelease.upload_distroseriesID,
-            PackageUpload.archive == SourcePackageRelease.upload_archiveID,
+            == SourcePackageRelease.upload_distroseries_id,
+            PackageUpload.archive == SourcePackageRelease.upload_archive_id,
             PackageUploadSource.sourcepackagerelease
             == SourcePackageRelease.id,
             SourcePackageRelease.id
@@ -2501,9 +2505,9 @@ def get_current_source_releases(
             Or(*series_clauses),
             *extra_clauses,
         )
-        .config(distinct=(SourcePackageRelease.sourcepackagenameID, key_col))
+        .config(distinct=(SourcePackageRelease.sourcepackagename_id, key_col))
         .order_by(
-            SourcePackageRelease.sourcepackagenameID,
+            SourcePackageRelease.sourcepackagename_id,
             key_col,
             Desc(SourcePackagePublishingHistory.id),
         )
diff --git a/lib/lp/soyuz/model/queue.py b/lib/lp/soyuz/model/queue.py
index e686aa4..89fe2f9 100644
--- a/lib/lp/soyuz/model/queue.py
+++ b/lib/lp/soyuz/model/queue.py
@@ -1655,7 +1655,7 @@ class PackageUploadSet:
             Join(
                 SourcePackageName,
                 SourcePackageName.id
-                == SourcePackageRelease.sourcepackagenameID,
+                == SourcePackageRelease.sourcepackagename_id,
             ),
         )
 
@@ -1886,7 +1886,7 @@ def prefill_packageupload_caches(uploads, puses, pubs, pucs, logs):
     load_related(BinaryPackageName, bprs, ["binarypackagename_id"])
     sprs = source_sprs + binary_sprs
 
-    load_related(SourcePackageName, sprs, ["sourcepackagenameID"])
+    load_related(SourcePackageName, sprs, ["sourcepackagename_id"])
     load_related(Section, sprs + bprs, ["section_id"])
     load_related(Component, sprs, ["component_id"])
     load_related(LibraryFileAlias, uploads, ["changes_file_id"])
diff --git a/lib/lp/soyuz/model/sourcepackagerelease.py b/lib/lp/soyuz/model/sourcepackagerelease.py
index 8c27732..6edb2fe 100644
--- a/lib/lp/soyuz/model/sourcepackagerelease.py
+++ b/lib/lp/soyuz/model/sourcepackagerelease.py
@@ -13,14 +13,13 @@ import re
 from datetime import datetime, timezone
 
 import apt_pkg
-import six
 from debian.changelog import (
     Changelog,
     ChangelogCreateError,
     ChangelogParseError,
 )
-from storm.expr import Join
-from storm.locals import Desc, Int, Reference, Unicode
+from storm.expr import Coalesce, Join, Sum
+from storm.locals import DateTime, Desc, Int, Reference, Unicode
 from storm.store import Store
 from zope.component import getUtility
 from zope.interface import implementer
@@ -33,13 +32,11 @@ from lp.registry.interfaces.sourcepackage import (
     SourcePackageType,
     SourcePackageUrgency,
 )
-from lp.services.database.constants import UTC_NOW
-from lp.services.database.datetimecol import UtcDateTimeCol
+from lp.services.database.constants import DEFAULT, UTC_NOW
 from lp.services.database.decoratedresultset import DecoratedResultSet
 from lp.services.database.enumcol import DBEnum
 from lp.services.database.interfaces import IStore
-from lp.services.database.sqlbase import SQLBase, cursor, sqlvalues
-from lp.services.database.sqlobject import ForeignKey, StringCol
+from lp.services.database.stormbase import StormBase
 from lp.services.librarian.model import LibraryFileAlias, LibraryFileContent
 from lp.services.propertycache import cachedproperty, get_property_cache
 from lp.soyuz.interfaces.archive import MAIN_ARCHIVE_PURPOSES
@@ -54,32 +51,26 @@ from lp.soyuz.model.queue import PackageUpload, PackageUploadSource
 
 
 @implementer(ISourcePackageRelease)
-class SourcePackageRelease(SQLBase):
-    _table = "SourcePackageRelease"
+class SourcePackageRelease(StormBase):
+    __storm_table__ = "SourcePackageRelease"
 
+    id = Int(primary=True)
     # DB constraint: non-nullable for SourcePackageType.DPKG.
     section_id = Int(name="section", allow_none=True)
     section = Reference(section_id, "Section.id")
-    creator = ForeignKey(
-        dbName="creator",
-        foreignKey="Person",
-        storm_validator=validate_public_person,
-        notNull=True,
+    creator_id = Int(
+        name="creator", validator=validate_public_person, allow_none=False
     )
+    creator = Reference(creator_id, "Person.id")
     # DB constraint: non-nullable for SourcePackageType.DPKG.
     component_id = Int(name="component", allow_none=True)
     component = Reference(component_id, "Component.id")
-    sourcepackagename = ForeignKey(
-        foreignKey="SourcePackageName",
-        dbName="sourcepackagename",
-        notNull=True,
-    )
-    maintainer = ForeignKey(
-        dbName="maintainer",
-        foreignKey="Person",
-        storm_validator=validate_public_person,
-        notNull=False,
+    sourcepackagename_id = Int(name="sourcepackagename", allow_none=False)
+    sourcepackagename = Reference(sourcepackagename_id, "SourcePackageName.id")
+    maintainer_id = Int(
+        name="maintainer", validator=validate_public_person, allow_none=True
     )
+    maintainer = Reference(maintainer_id, "Person.id")
     signing_key_owner_id = Int(name="signing_key_owner")
     signing_key_owner = Reference(signing_key_owner_id, "Person.id")
     signing_key_fingerprint = Unicode()
@@ -90,32 +81,37 @@ class SourcePackageRelease(SQLBase):
         default=SourcePackageUrgency.LOW,
         allow_none=True,
     )
-    dateuploaded = UtcDateTimeCol(
-        dbName="dateuploaded", notNull=True, default=UTC_NOW
+    dateuploaded = DateTime(
+        name="dateuploaded",
+        allow_none=False,
+        default=UTC_NOW,
+        tzinfo=timezone.utc,
+    )
+    dsc = Unicode(name="dsc")
+    version = Unicode(name="version", allow_none=False)
+    changelog_id = Int(name="changelog")
+    changelog = Reference(changelog_id, "LibraryFileAlias.id")
+    changelog_entry = Unicode(name="changelog_entry")
+    buildinfo_id = Int(name="buildinfo")
+    buildinfo = Reference(buildinfo_id, "LibraryFileAlias.id")
+    builddepends = Unicode(name="builddepends")
+    builddependsindep = Unicode(name="builddependsindep")
+    build_conflicts = Unicode(name="build_conflicts")
+    build_conflicts_indep = Unicode(name="build_conflicts_indep")
+    architecturehintlist = Unicode(
+        name="architecturehintlist", allow_none=False
     )
-    dsc = StringCol(dbName="dsc")
-    version = StringCol(dbName="version", notNull=True)
-    changelog = ForeignKey(foreignKey="LibraryFileAlias", dbName="changelog")
-    changelog_entry = StringCol(dbName="changelog_entry")
-    buildinfo = ForeignKey(foreignKey="LibraryFileAlias", dbName="buildinfo")
-    builddepends = StringCol(dbName="builddepends")
-    builddependsindep = StringCol(dbName="builddependsindep")
-    build_conflicts = StringCol(dbName="build_conflicts")
-    build_conflicts_indep = StringCol(dbName="build_conflicts_indep")
-    architecturehintlist = StringCol(dbName="architecturehintlist")
-    homepage = StringCol(dbName="homepage")
+    homepage = Unicode(name="homepage")
     format = DBEnum(
         name="format",
         enum=SourcePackageType,
         default=SourcePackageType.DPKG,
         allow_none=False,
     )
-    upload_distroseries = ForeignKey(
-        foreignKey="DistroSeries", dbName="upload_distroseries"
-    )
-    upload_archive = ForeignKey(
-        foreignKey="Archive", dbName="upload_archive", notNull=True
-    )
+    upload_distroseries_id = Int(name="upload_distroseries", allow_none=False)
+    upload_distroseries = Reference(upload_distroseries_id, "DistroSeries.id")
+    upload_archive_id = Int(name="upload_archive", allow_none=False)
+    upload_archive = Reference(upload_archive_id, "Archive.id")
 
     # DB constraint: at most one of source_package_recipe_build and ci_build
     # is non-NULL.
@@ -128,36 +124,84 @@ class SourcePackageRelease(SQLBase):
     ci_build_id = Int(name="ci_build", allow_none=True)
     ci_build = Reference(ci_build_id, "CIBuild.id")
 
-    # XXX cprov 2006-09-26: Those fields are set as notNull and required in
-    # ISourcePackageRelease, however they can't be not NULL in DB since old
-    # records doesn't satisfy this condition. We will sort it before using
-    # 'NoMoreAptFtparchive' implementation for PRIMARY archive. For PPA
-    # (primary target) we don't need to populate old records.
-    dsc_maintainer_rfc822 = StringCol(dbName="dsc_maintainer_rfc822")
-    dsc_standards_version = StringCol(dbName="dsc_standards_version")
+    dsc_maintainer_rfc822 = Unicode(name="dsc_maintainer_rfc822")
+    dsc_standards_version = Unicode(name="dsc_standards_version")
     # DB constraint: non-nullable for SourcePackageType.DPKG.
-    dsc_format = StringCol(dbName="dsc_format")
-    dsc_binaries = StringCol(dbName="dsc_binaries")
-
-    _user_defined_fields = StringCol(dbName="user_defined_fields")
-
-    def __init__(self, *args, **kwargs):
-        if "user_defined_fields" in kwargs:
-            kwargs["_user_defined_fields"] = json.dumps(
-                kwargs["user_defined_fields"]
-            )
-            del kwargs["user_defined_fields"]
-        # copyright isn't on the Storm class, since we don't want it
-        # loaded every time. Set it separately.
-        if "copyright" in kwargs:
-            copyright = kwargs.pop("copyright")
-        super().__init__(*args, **kwargs)
-        # PostgreSQL text columns can't contain null
-        # characters, so remove them as this is only
-        # used for display
+    dsc_format = Unicode(name="dsc_format")
+    dsc_binaries = Unicode(name="dsc_binaries")
+
+    _user_defined_fields = Unicode(name="user_defined_fields")
+
+    def __init__(
+        self,
+        creator,
+        sourcepackagename,
+        version,
+        architecturehintlist,
+        format,
+        upload_distroseries,
+        upload_archive,
+        section=None,
+        component=None,
+        maintainer=None,
+        signing_key_owner=None,
+        signing_key_fingerprint=None,
+        urgency=None,
+        dateuploaded=DEFAULT,
+        dsc=None,
+        changelog=None,
+        changelog_entry=None,
+        buildinfo=None,
+        builddepends=None,
+        builddependsindep=None,
+        build_conflicts=None,
+        build_conflicts_indep=None,
+        homepage=None,
+        source_package_recipe_build=None,
+        ci_build=None,
+        dsc_maintainer_rfc822=None,
+        dsc_standards_version=None,
+        dsc_format=None,
+        dsc_binaries=None,
+        user_defined_fields=None,
+        copyright=None,
+    ):
+        super().__init__()
+        self.creator = creator
+        self.sourcepackagename = sourcepackagename
+        self.version = version
+        self.architecturehintlist = architecturehintlist
+        self.format = format
+        self.upload_distroseries = upload_distroseries
+        self.upload_archive = upload_archive
+        self.section = section
+        self.component = component
+        self.maintainer = maintainer
+        self.signing_key_owner = signing_key_owner
+        self.signing_key_fingerprint = signing_key_fingerprint
+        self.urgency = urgency
+        self.dateuploaded = dateuploaded
+        self.dsc = dsc
+        self.changelog = changelog
+        self.changelog_entry = changelog_entry
+        self.buildinfo = buildinfo
+        self.builddepends = builddepends
+        self.builddependsindep = builddependsindep
+        self.build_conflicts = build_conflicts
+        self.build_conflicts_indep = build_conflicts_indep
+        self.homepage = homepage
+        self.source_package_recipe_build = source_package_recipe_build
+        self.ci_build = ci_build
+        self.dsc_maintainer_rfc822 = dsc_maintainer_rfc822
+        self.dsc_standards_version = dsc_standards_version
+        self.dsc_format = dsc_format
+        self.dsc_binaries = dsc_binaries
+        if user_defined_fields is not None:
+            self._user_defined_fields = json.dumps(user_defined_fields)
         if copyright is not None:
-            copyright = copyright.replace("\0", "")
-        self.copyright = copyright
+            # PostgreSQL text columns can't contain null characters, so
+            # remove them as this is only used for display.
+            self.copyright = copyright.replace("\0", "")
 
     def __repr__(self):
         """Returns an informative representation of a SourcePackageRelease."""
@@ -183,8 +227,6 @@ class SourcePackageRelease(SQLBase):
         """See `ISourcePackageRelease`."""
         store = Store.of(self)
         store.flush()
-        if content is not None:
-            content = six.ensure_text(content)
         store.execute(
             "UPDATE sourcepackagerelease SET copyright=%s WHERE id=%s",
             (content, self.id),
@@ -216,19 +258,24 @@ class SourcePackageRelease(SQLBase):
     @property
     def builds(self):
         """See `ISourcePackageRelease`."""
+        # Circular import.
+        from lp.soyuz.model.archive import Archive
+
         # Excluding PPA builds may seem like a strange thing to do, but,
         # since Archive.copyPackage can copy packages across archives, a
         # build may well have a different archive to the corresponding
         # sourcepackagerelease.
-        return BinaryPackageBuild.select(
-            """
-            source_package_release = %s AND
-            archive.id = binarypackagebuild.archive AND
-            archive.purpose IN %s
-            """
-            % sqlvalues(self.id, MAIN_ARCHIVE_PURPOSES),
-            orderBy=["-date_created", "id"],
-            clauseTables=["Archive"],
+        return (
+            IStore(BinaryPackageBuild)
+            .find(
+                BinaryPackageBuild,
+                BinaryPackageBuild.source_package_release == self,
+                BinaryPackageBuild.archive == Archive.id,
+                Archive.purpose.is_in(MAIN_ARCHIVE_PURPOSES),
+            )
+            .order_by(
+                Desc(BinaryPackageBuild.date_created), BinaryPackageBuild.id
+            )
         )
 
     @property
@@ -339,34 +386,32 @@ class SourcePackageRelease(SQLBase):
 
     def getPackageSize(self):
         """See ISourcePackageRelease."""
-        size_query = """
-            SELECT
-                SUM(LibraryFileContent.filesize)/1024.0
-            FROM
-                SourcePackagereLease
-                JOIN SourcePackageReleaseFile ON
-                    SourcePackageReleaseFile.sourcepackagerelease =
-                    SourcePackageRelease.id
-                JOIN LibraryFileAlias ON
-                    SourcePackageReleaseFile.libraryfile =
-                    LibraryFileAlias.id
-                JOIN LibraryFileContent ON
-                    LibraryFileAlias.content = LibraryFileContent.id
-            WHERE
-                SourcePackageRelease.id = %s
-            """ % sqlvalues(
-            self
+        return float(
+            Store.of(self)
+            .using(
+                SourcePackageRelease,
+                Join(
+                    SourcePackageReleaseFile,
+                    SourcePackageReleaseFile.sourcepackagerelease
+                    == SourcePackageRelease.id,
+                ),
+                Join(
+                    LibraryFileAlias,
+                    SourcePackageReleaseFile.libraryfile
+                    == LibraryFileAlias.id,
+                ),
+                Join(
+                    LibraryFileContent,
+                    LibraryFileAlias.content == LibraryFileContent.id,
+                ),
+            )
+            .find(
+                Coalesce(Sum(LibraryFileContent.filesize) / 1024.0, 0.0),
+                SourcePackageRelease.id == self.id,
+            )
+            .one()
         )
 
-        cur = cursor()
-        cur.execute(size_query)
-        results = cur.fetchone()
-
-        if len(results) == 1 and results[0] is not None:
-            return float(results[0])
-        else:
-            return 0.0
-
     def override(self, component=None, section=None, urgency=None):
         """See ISourcePackageRelease."""
         if component is not None:
@@ -528,5 +573,4 @@ class SourcePackageRelease(SQLBase):
         except ChangelogParseError:
             return None
 
-        output = "\n\n".join(chunks)
-        return six.ensure_text(output, "utf-8", "replace")
+        return "\n\n".join(chunks)
diff --git a/lib/lp/soyuz/scripts/gina/handlers.py b/lib/lp/soyuz/scripts/gina/handlers.py
index 5af9a8b..b5b68ae 100644
--- a/lib/lp/soyuz/scripts/gina/handlers.py
+++ b/lib/lp/soyuz/scripts/gina/handlers.py
@@ -652,19 +652,19 @@ class SourcePackageHandler:
         )
 
         # Create the SourcePackageRelease (SPR)
-        componentID = self.distro_handler.getComponentByName(src.component).id
-        sectionID = self.distro_handler.ensureSection(src.section).id
+        component = self.distro_handler.getComponentByName(src.component)
+        section = self.distro_handler.ensureSection(src.section)
         maintainer_line = "%s <%s>" % (displayname, emailaddress)
         name = self.ensureSourcePackageName(src.package)
         kwargs = {}
         if src._user_defined:
             kwargs["user_defined_fields"] = src._user_defined
         spr = SourcePackageRelease(
-            section=sectionID,
-            creator=maintainer.id,
-            component=componentID,
-            sourcepackagename=name.id,
-            maintainer=maintainer.id,
+            section=section,
+            creator=maintainer,
+            component=component,
+            sourcepackagename=name,
+            maintainer=maintainer,
             signing_key_owner=key.owner if key else None,
             signing_key_fingerprint=key.fingerprint if key else None,
             urgency=ChangesFile.urgency_map[src.urgency],
diff --git a/lib/lp/soyuz/scripts/retrydepwait.py b/lib/lp/soyuz/scripts/retrydepwait.py
index 45cfeb0..5b6d57f 100644
--- a/lib/lp/soyuz/scripts/retrydepwait.py
+++ b/lib/lp/soyuz/scripts/retrydepwait.py
@@ -49,7 +49,7 @@ class RetryDepwaitTunableLoop(TunableLoop):
         sprs = load_related(
             SourcePackageRelease, bpbs, ["source_package_release_id"]
         )
-        load_related(SourcePackageName, sprs, ["sourcepackagenameID"])
+        load_related(SourcePackageName, sprs, ["sourcepackagename_id"])
         chroots = IStore(PocketChroot).find(
             PocketChroot,
             PocketChroot.distroarchseriesID.is_in(
diff --git a/lib/lp/soyuz/stories/soyuz/xx-queue-pages-motu.rst b/lib/lp/soyuz/stories/soyuz/xx-queue-pages-motu.rst
index 076a1b3..62a0396 100644
--- a/lib/lp/soyuz/stories/soyuz/xx-queue-pages-motu.rst
+++ b/lib/lp/soyuz/stories/soyuz/xx-queue-pages-motu.rst
@@ -89,8 +89,8 @@ permission to manipulate them.
     >>> mozilla = getUtility(IBinaryPackageNameSet).queryByName(
     ...     "mozilla-firefox"
     ... )
-    >>> for source in SourcePackageRelease.selectBy(
-    ...     sourcepackagename=alsa_utils
+    >>> for source in IStore(SourcePackageRelease).find(
+    ...     SourcePackageRelease, sourcepackagename=alsa_utils
     ... ):
     ...     source.component = universe
     >>> for binary in IStore(BinaryPackageRelease).find(
diff --git a/lib/lp/soyuz/tests/test_packagediff.py b/lib/lp/soyuz/tests/test_packagediff.py
index da31f3b..b86a26f 100644
--- a/lib/lp/soyuz/tests/test_packagediff.py
+++ b/lib/lp/soyuz/tests/test_packagediff.py
@@ -5,11 +5,12 @@
 
 import io
 import os.path
-from datetime import datetime
+from datetime import datetime, timezone
 from textwrap import dedent
 
 import transaction
 from fixtures import EnvironmentVariableFixture
+from storm.expr import And
 from zope.security.proxy import removeSecurityProxy
 from zope.testbrowser.browser import LinkNotFoundError
 
@@ -17,12 +18,13 @@ from lp.archivepublisher.config import ArchivePurpose
 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 sqlvalues
+from lp.services.database.stormexpr import BulkUpdate
 from lp.services.job.interfaces.job import JobType
 from lp.services.job.model.job import Job
 from lp.services.librarian.client import ILibrarianClient
+from lp.services.librarian.model import LibraryFileAlias
 from lp.soyuz.enums import PackageDiffStatus
-from lp.soyuz.model.archive import Archive
+from lp.soyuz.model.files import SourcePackageReleaseFile
 from lp.testing import (
     BrowserTestCase,
     TestCaseWithFactory,
@@ -96,25 +98,25 @@ class TestPackageDiffs(TestCaseWithFactory):
         """Expire the files associated with the given source package in the
         librarian."""
         assert expire or delete
-        query = "UPDATE LibraryFileAlias lfa SET "
+        update_map = {}
         if expire:
-            query += "expires = %s" % sqlvalues(datetime.utcnow())
-        if expire and delete:
-            query += ", "
+            update_map[LibraryFileAlias.expires] = datetime.now(timezone.utc)
         if delete:
-            query += "content = NULL"
-        query += """
-            FROM
-                SourcePackageRelease spr, SourcePackageReleaseFile sprf
-            WHERE
-                spr.id = %s
-                AND sprf.SourcePackageRelease = spr.id
-                AND sprf.libraryfile = lfa.id
-            """ % sqlvalues(
-            source.id
-        )
+            update_map[LibraryFileAlias.contentID] = None
         with dbuser("launchpad"):
-            IStore(Archive).execute(query)
+            IStore(LibraryFileAlias).execute(
+                BulkUpdate(
+                    update_map,
+                    table=LibraryFileAlias,
+                    values=SourcePackageReleaseFile,
+                    where=And(
+                        SourcePackageReleaseFile.sourcepackagerelease
+                        == source,
+                        SourcePackageReleaseFile.libraryfile
+                        == LibraryFileAlias.id,
+                    ),
+                )
+            )
 
     def test_packagediff_with_expired_and_deleted_lfas(self):
         # Test the case where files required for the diff are expired *and*
diff --git a/lib/lp/soyuz/vocabularies.py b/lib/lp/soyuz/vocabularies.py
index 28b654f..f02c01e 100644
--- a/lib/lp/soyuz/vocabularies.py
+++ b/lib/lp/soyuz/vocabularies.py
@@ -73,9 +73,9 @@ class FilteredDistroArchSeriesVocabulary(SQLObjectVocabularyBase):
                 yield self.toTerm(distroarchseries)
 
 
-class PackageReleaseVocabulary(SQLObjectVocabularyBase):
+class PackageReleaseVocabulary(StormVocabularyBase):
     _table = SourcePackageRelease
-    _orderBy = "id"
+    _order_by = "id"
 
     def toTerm(self, obj):
         return SimpleTerm(obj, obj.id, obj.name + " " + obj.version)
diff --git a/lib/lp/translations/doc/sourcepackagerelease-translations.rst b/lib/lp/translations/doc/sourcepackagerelease-translations.rst
index 30eb0e3..b5e9a55 100644
--- a/lib/lp/translations/doc/sourcepackagerelease-translations.rst
+++ b/lib/lp/translations/doc/sourcepackagerelease-translations.rst
@@ -43,8 +43,9 @@ Commit, so uploaded contents are available in the current test.
 We will use an arbitrary source package release from the sampledata, and
 create a PackageUpload with it.
 
+    >>> from lp.services.database.interfaces import IStore
     >>> from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
-    >>> spr_test = SourcePackageRelease.get(20)
+    >>> spr_test = IStore(SourcePackageRelease).get(SourcePackageRelease, 20)
     >>> sp_test = spr_test.upload_distroseries.getSourcePackage(
     ...     spr_test.sourcepackagename
     ... )