← Back to team overview

launchpad-reviewers team mailing list archive

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

 

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

Commit message:
Convert DistroSeries to Storm

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/450381
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:stormify-distroseries into launchpad:master.
diff --git a/lib/lp/bugs/model/bugtask.py b/lib/lp/bugs/model/bugtask.py
index 6752c85..d66c62a 100644
--- a/lib/lp/bugs/model/bugtask.py
+++ b/lib/lp/bugs/model/bugtask.py
@@ -1282,7 +1282,7 @@ class BugTask(StormBase):
                         BugTask,
                         BugTask.bug_id == self.bug_id,
                         BugTask.distroseries_id == DistroSeries.id,
-                        DistroSeries.distributionID.is_in(
+                        DistroSeries.distribution_id.is_in(
                             distro.id for distro in distros if distro
                         ),
                     )
@@ -2131,7 +2131,7 @@ class BugTaskSet:
                     Distribution.id.is_in(
                         (
                             BugTaskFlat.distribution_id,
-                            DistroSeries.distributionID,
+                            DistroSeries.distribution_id,
                         )
                     ),
                 ),
diff --git a/lib/lp/bugs/model/bugtasksearch.py b/lib/lp/bugs/model/bugtasksearch.py
index 9f6e248..8de8c55 100644
--- a/lib/lp/bugs/model/bugtasksearch.py
+++ b/lib/lp/bugs/model/bugtasksearch.py
@@ -548,7 +548,7 @@ def _build_query(params):
             # distroseries. We only include these when we need to.
             if params.distroseries is not None:
                 distroseries_id = params.distroseries.id
-                parent_distro_id = params.distroseries.distributionID
+                parent_distro_id = params.distroseries.distribution_id
             else:
                 distroseries_id = 0
                 parent_distro_id = 0
diff --git a/lib/lp/charms/model/charmrecipebuild.py b/lib/lp/charms/model/charmrecipebuild.py
index 998994e..6024b31 100644
--- a/lib/lp/charms/model/charmrecipebuild.py
+++ b/lib/lp/charms/model/charmrecipebuild.py
@@ -527,7 +527,7 @@ class CharmRecipeBuildSet(SpecificBuildFarmJobSourceMixin):
         distroserieses = load_related(
             DistroSeries, distroarchserieses, ["distroseries_id"]
         )
-        load_related(Distribution, distroserieses, ["distributionID"])
+        load_related(Distribution, distroserieses, ["distribution_id"])
         recipes = load_related(CharmRecipe, builds, ["recipe_id"])
         getUtility(ICharmRecipeSet).preloadDataForRecipes(recipes)
         build_ids = set(map(attrgetter("id"), builds))
diff --git a/lib/lp/code/model/cibuild.py b/lib/lp/code/model/cibuild.py
index d157ccb..8c32605 100644
--- a/lib/lp/code/model/cibuild.py
+++ b/lib/lp/code/model/cibuild.py
@@ -908,7 +908,7 @@ class CIBuildSet(SpecificBuildFarmJobSourceMixin):
         distroseries = load_related(
             DistroSeries, distroarchseries, ["distroseries_id"]
         )
-        load_related(Distribution, distroseries, ["distributionID"])
+        load_related(Distribution, distroseries, ["distribution_id"])
 
     def getByBuildFarmJobs(self, build_farm_jobs):
         """See `ISpecificBuildFarmJobSource`."""
diff --git a/lib/lp/code/model/sourcepackagerecipebuild.py b/lib/lp/code/model/sourcepackagerecipebuild.py
index c75ed36..1ec64c9 100644
--- a/lib/lp/code/model/sourcepackagerecipebuild.py
+++ b/lib/lp/code/model/sourcepackagerecipebuild.py
@@ -330,7 +330,7 @@ class SourcePackageRecipeBuild(
         archives = load_related(Archive, builds, ["archive_id"])
         load_related(Person, archives, ["ownerID"])
         distroseries = load_related(DistroSeries, builds, ["distroseries_id"])
-        load_related(Distribution, distroseries, ["distributionID"])
+        load_related(Distribution, distroseries, ["distribution_id"])
         sprs = load_related(SourcePackageRecipe, builds, ["recipe_id"])
         SourcePackageRecipe.preLoadDataForSourcePackageRecipes(sprs)
 
diff --git a/lib/lp/code/vocabularies/sourcepackagerecipe.py b/lib/lp/code/vocabularies/sourcepackagerecipe.py
index f500190..2c6b8b6 100644
--- a/lib/lp/code/vocabularies/sourcepackagerecipe.py
+++ b/lib/lp/code/vocabularies/sourcepackagerecipe.py
@@ -17,16 +17,13 @@ from lp.registry.interfaces.distroseries import IDistroSeriesSet
 from lp.registry.model.distroseries import DistroSeries
 from lp.services.webapp.interfaces import ILaunchBag
 from lp.services.webapp.sorting import sorted_dotted_numbers
-from lp.services.webapp.vocabulary import (
-    IHugeVocabulary,
-    SQLObjectVocabularyBase,
-)
+from lp.services.webapp.vocabulary import IHugeVocabulary, StormVocabularyBase
 from lp.soyuz.interfaces.archive import IArchiveSet
 from lp.soyuz.vocabularies import make_archive_vocabulary
 
 
 @implementer(IHugeVocabulary)
-class BuildableDistroSeries(SQLObjectVocabularyBase):
+class BuildableDistroSeries(StormVocabularyBase):
     _table = DistroSeries
 
     def toTerm(self, obj):
diff --git a/lib/lp/registry/doc/distroseries.rst b/lib/lp/registry/doc/distroseries.rst
index 532db53..0317c68 100644
--- a/lib/lp/registry/doc/distroseries.rst
+++ b/lib/lp/registry/doc/distroseries.rst
@@ -86,8 +86,9 @@ And IHasTranslationImports:
 
 To search the set of IDistroSeriess, use IDistroSeriesSet.search:
 
+    >>> from storm.expr import Desc
     >>> ubuntu_releases = distroseriesset.search(
-    ...     distribution=ubuntu, isreleased=True, orderBy="-datereleased"
+    ...     distribution=ubuntu, isreleased=True, orderBy=Desc("datereleased")
     ... )
     >>> for release in ubuntu_releases:
     ...     print(release.name)
diff --git a/lib/lp/registry/doc/sourcepackage.rst b/lib/lp/registry/doc/sourcepackage.rst
index ca27efe..6441d5d 100644
--- a/lib/lp/registry/doc/sourcepackage.rst
+++ b/lib/lp/registry/doc/sourcepackage.rst
@@ -278,8 +278,8 @@ First, let's get some useful objects from the db.
     >>> pmount = sourcepackagenameset["pmount"]
 
     >>> from lp.registry.model.distroseries import DistroSeries
-    >>> warty = DistroSeries.get(1)
-    >>> hoary = DistroSeries.get(3)
+    >>> warty = IStore(DistroSeries).get(DistroSeries, 1)
+    >>> hoary = IStore(DistroSeries).get(DistroSeries, 3)
 
 Now let's make sure that we can see a productseries for a source
 package.
diff --git a/lib/lp/registry/interfaces/distroseries.py b/lib/lp/registry/interfaces/distroseries.py
index 1e33102..bcb5a24 100644
--- a/lib/lp/registry/interfaces/distroseries.py
+++ b/lib/lp/registry/interfaces/distroseries.py
@@ -273,7 +273,7 @@ class IDistroSeriesPublic(
             description=_("The distribution for which this is a series."),
         )
     )
-    distributionID = Attribute("The distribution ID.")
+    distribution_id = Attribute("The distribution ID.")
     named_version = Attribute("The combined display name and version.")
     parent = Attribute("The structural parent of this series - the distro")
     components = Attribute("The series components.")
diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py
index 8abb04f..23fdb69 100644
--- a/lib/lp/registry/model/distribution.py
+++ b/lib/lp/registry/model/distribution.py
@@ -752,12 +752,10 @@ class Distribution(
     enable_bug_expiration = BoolCol(
         dbName="enable_bug_expiration", notNull=True, default=False
     )
-    translation_focus = ForeignKey(
-        dbName="translation_focus",
-        foreignKey="DistroSeries",
-        notNull=False,
-        default=None,
+    translation_focus_id = Int(
+        name="translation_focus", allow_none=True, default=None
     )
+    translation_focus = Reference(translation_focus_id, "DistroSeries.id")
     date_created = UtcDateTimeCol(notNull=False, default=UTC_NOW)
     language_pack_admin = ForeignKey(
         dbName="language_pack_admin",
@@ -1001,16 +999,16 @@ class Distribution(
         """See `IDistribution`."""
         ParentDistroSeries = ClassAlias(DistroSeries)
         # XXX rvb 2011-04-08 bug=754750: The clause
-        # 'DistroSeries.distributionID!=self.id' is only required
+        # 'DistroSeries.distribution_id!=self.id' is only required
         # because the previous_series attribute has been (mis-)used
         # to denote other relations than proper derivation
         # relationships. We should be rid of this condition once
         # the bug is fixed.
         ret = Store.of(self).find(
             DistroSeries,
-            ParentDistroSeries.id == DistroSeries.previous_seriesID,
-            ParentDistroSeries.distributionID == self.id,
-            DistroSeries.distributionID != self.id,
+            ParentDistroSeries.id == DistroSeries.previous_series_id,
+            ParentDistroSeries.distribution_id == self.id,
+            DistroSeries.distribution_id != self.id,
         )
         return ret.config(distinct=True).order_by(
             Desc(DistroSeries.date_created)
@@ -1067,7 +1065,7 @@ class Distribution(
         ds_ids = Select(
             DistroSeries.id,
             tables=[DistroSeries],
-            where=DistroSeries.distributionID == self.id,
+            where=DistroSeries.distribution_id == self.id,
         )
         clauses = [
             DistroSeries.id.is_in(ds_ids),
@@ -2093,6 +2091,7 @@ class Distribution(
         # RBC 20100816.
         del get_property_cache(self).series
 
+        IStore(series).flush()
         return series
 
     @property
@@ -2461,7 +2460,7 @@ class DistributionSet:
                 SourcePackagePublishingHistory.distroseries_id
                 == DistroSeries.id
             ],
-            DistroSeries.distributionID,
+            DistroSeries.distribution_id,
         )
         result = {}
         for spr, distro_id in releases:
@@ -2478,9 +2477,9 @@ class DistributionSet:
             IStore(DistroSeries)
             .find(
                 Distribution,
-                Distribution.id == DistroSeries.distributionID,
+                Distribution.id == DistroSeries.distribution_id,
                 DistroSeries.id == DistroSeriesParent.derived_series_id,
-                DistroSeries.distributionID != ubuntu_id,
+                DistroSeries.distribution_id != ubuntu_id,
             )
             .config(distinct=True)
         )
diff --git a/lib/lp/registry/model/distroseries.py b/lib/lp/registry/model/distroseries.py
index 2b43af8..22d2895 100644
--- a/lib/lp/registry/model/distroseries.py
+++ b/lib/lp/registry/model/distroseries.py
@@ -11,6 +11,7 @@ __all__ = [
 ]
 
 import collections
+from datetime import timezone
 from io import BytesIO
 from operator import itemgetter
 from typing import List
@@ -18,7 +19,15 @@ from typing import List
 import apt_pkg
 from lazr.delegates import delegate_to
 from storm.expr import SQL, And, Column, Desc, Is, Join, Not, Or, Select, Table
-from storm.locals import JSON, Int, Reference, ReferenceSet
+from storm.locals import (
+    JSON,
+    Bool,
+    DateTime,
+    Int,
+    Reference,
+    ReferenceSet,
+    Unicode,
+)
 from storm.store import Store
 from zope.component import getUtility
 from zope.interface import implementer
@@ -67,17 +76,11 @@ from lp.registry.model.series import SeriesMixin
 from lp.registry.model.sourcepackage import SourcePackage
 from lp.registry.model.sourcepackagename import SourcePackageName
 from lp.services.database.constants import DEFAULT, UTC_NOW
-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 IStore
-from lp.services.database.sqlbase import SQLBase, sqlvalues
-from lp.services.database.sqlobject import (
-    BoolCol,
-    ForeignKey,
-    IntCol,
-    StringCol,
-)
+from lp.services.database.sqlbase import sqlvalues
+from lp.services.database.stormbase import StormBase
 from lp.services.database.stormexpr import WithMaterialized, fti_search
 from lp.services.librarian.interfaces import ILibraryFileAliasSet
 from lp.services.librarian.model import LibraryFileAlias
@@ -167,7 +170,7 @@ DEFAULT_INDEX_COMPRESSORS = [
     ISeriesBugTarget,
 )
 class DistroSeries(
-    SQLBase,
+    StormBase,
     SeriesMixin,
     BugTargetBase,
     HasSpecificationsMixin,
@@ -178,48 +181,47 @@ class DistroSeries(
 ):
     """A particular series of a distribution."""
 
-    _table = "DistroSeries"
-    _defaultOrder = ["distribution", "version"]
-
-    distribution = ForeignKey(
-        dbName="distribution", foreignKey="Distribution", notNull=True
-    )
-    name = StringCol()
-    display_name = StringCol(dbName="displayname", notNull=True)
-    title = StringCol(notNull=True)
-    description = StringCol(notNull=True)
-    version = StringCol(notNull=True)
+    __storm_table__ = "DistroSeries"
+    __storm_order__ = ["distribution", "version"]
+
+    id = Int(primary=True)
+    distribution_id = Int(name="distribution", allow_none=False)
+    distribution = Reference(distribution_id, "Distribution.id")
+    name = Unicode()
+    display_name = Unicode(name="displayname", allow_none=False)
+    title = Unicode(allow_none=False)
+    description = Unicode(allow_none=False)
+    version = Unicode(allow_none=False)
     status = DBEnum(name="releasestatus", allow_none=False, enum=SeriesStatus)
-    date_created = UtcDateTimeCol(notNull=False, default=UTC_NOW)
-    datereleased = UtcDateTimeCol(notNull=False, default=None)
-    previous_series = ForeignKey(
-        dbName="parent_series", foreignKey="DistroSeries", notNull=False
+    date_created = DateTime(
+        allow_none=True, default=UTC_NOW, tzinfo=timezone.utc
     )
-    registrant = ForeignKey(
-        dbName="registrant",
-        foreignKey="Person",
-        storm_validator=validate_public_person,
-        notNull=True,
+    datereleased = DateTime(allow_none=True, default=None, tzinfo=timezone.utc)
+    previous_series_id = Int(name="parent_series", allow_none=True)
+    previous_series = Reference(previous_series_id, "DistroSeries.id")
+    registrant_id = Int(
+        name="registrant", validator=validate_public_person, allow_none=False
     )
-    driver = ForeignKey(
-        dbName="driver",
-        foreignKey="Person",
-        storm_validator=validate_public_person,
-        notNull=False,
+    registrant = Reference(registrant_id, "Person.id")
+    driver_id = Int(
+        name="driver",
+        validator=validate_public_person,
+        allow_none=True,
         default=None,
     )
-    changeslist = StringCol(notNull=False, default=None)
+    driver = Reference(driver_id, "Person.id")
+    changeslist = Unicode(allow_none=True, default=None)
     nominatedarchindep_id = Int(
         name="nominatedarchindep", allow_none=True, default=None
     )
     nominatedarchindep = Reference(
         nominatedarchindep_id, "DistroArchSeries.id"
     )
-    messagecount = IntCol(notNull=True, default=0)
-    binarycount = IntCol(notNull=True, default=DEFAULT)
-    sourcecount = IntCol(notNull=True, default=DEFAULT)
-    defer_translation_imports = BoolCol(notNull=True, default=True)
-    hide_all_translations = BoolCol(notNull=True, default=True)
+    messagecount = Int(allow_none=False, default=0)
+    binarycount = Int(allow_none=False, default=DEFAULT)
+    sourcecount = Int(allow_none=False, default=DEFAULT)
+    defer_translation_imports = Bool(allow_none=False, default=True)
+    hide_all_translations = Bool(allow_none=False, default=True)
     language_pack_base_id = Int(
         name="language_pack_base", allow_none=True, default=None
     )
@@ -234,7 +236,7 @@ class DistroSeries(
     language_pack_proposed = Reference(
         language_pack_proposed_id, "LanguagePack.id"
     )
-    language_pack_full_export_requested = BoolCol(notNull=True, default=False)
+    language_pack_full_export_requested = Bool(allow_none=False, default=False)
     publishing_options = JSON("publishing_options")
 
     language_packs = ReferenceSet(
@@ -249,21 +251,41 @@ class DistroSeries(
         "Section.id",
     )
 
-    def __init__(self, *args, **kwargs):
-        if "publishing_options" not in kwargs:
-            kwargs["publishing_options"] = {
-                "backports_not_automatic": False,
-                "proposed_not_automatic": False,
-                "include_long_descriptions": True,
-                "index_compressors": [
-                    compressor.title
-                    for compressor in DEFAULT_INDEX_COMPRESSORS
-                ],
-                "publish_by_hash": False,
-                "advertise_by_hash": False,
-                "strict_supported_component_dependencies": True,
-            }
-        super().__init__(*args, **kwargs)
+    def __init__(
+        self,
+        distribution,
+        name,
+        display_name,
+        title,
+        summary,
+        description,
+        version,
+        status,
+        registrant,
+        previous_series=None,
+    ):
+        super().__init__()
+        self.distribution = distribution
+        self.name = name
+        self.display_name = display_name
+        self.title = title
+        self.summary = summary
+        self.description = description
+        self.version = version
+        self.status = status
+        self.registrant = registrant
+        self.previous_series = previous_series
+        self.publishing_options = {
+            "backports_not_automatic": False,
+            "proposed_not_automatic": False,
+            "include_long_descriptions": True,
+            "index_compressors": [
+                compressor.title for compressor in DEFAULT_INDEX_COMPRESSORS
+            ],
+            "publish_by_hash": False,
+            "advertise_by_hash": False,
+            "strict_supported_component_dependencies": True,
+        }
 
     @property
     def displayname(self):
@@ -593,7 +615,7 @@ class DistroSeries(
     ) AS spn_info"""
             % sqlvalues(
                 po_message_weight=self._current_sourcepackage_po_weight,
-                distroseries=self,
+                distroseries=self.id,
                 active_status=active_publishing_status,
                 primary=ArchivePurpose.PRIMARY,
             )
@@ -702,7 +724,7 @@ class DistroSeries(
                 ON SourcePackageName.id = messages.sourcepackagename
                 AND DistroSeries.id = messages.distroseries
             """ % sqlvalues(
-            distroseries=self, po_message_weight=po_message_weight
+            distroseries=self.id, po_message_weight=po_message_weight
         )
         joins = (
             """
@@ -732,7 +754,7 @@ class DistroSeries(
             AND archive.purpose = %(primary)s
             AND section.name != 'translations'
             """ % sqlvalues(
-            distroseries=self,
+            distroseries=self.id,
             active_status=active_publishing_status,
             primary=ArchivePurpose.PRIMARY,
         )
@@ -1668,13 +1690,13 @@ class DistroSeries(
         If the series isn't found, the distribution task is better than
         others.
         """
-        seriesID = self.id
-        distributionID = self.distributionID
+        series_id = self.id
+        distribution_id = self.distribution_id
 
         def weight_function(bugtask):
-            if bugtask.distroseries_id == seriesID:
+            if bugtask.distroseries_id == series_id:
                 return OrderedBugTask(1, bugtask.id, bugtask)
-            elif bugtask.distribution_id == distributionID:
+            elif bugtask.distribution_id == distribution_id:
                 return OrderedBugTask(2, bugtask.id, bugtask)
             else:
                 return OrderedBugTask(3, bugtask.id, bugtask)
@@ -1764,7 +1786,7 @@ class DistroSeries(
 class DistroSeriesSet:
     def get(self, distroseriesid):
         """See `IDistroSeriesSet`."""
-        return DistroSeries.get(distroseriesid)
+        return IStore(DistroSeries).get(DistroSeries, distroseriesid)
 
     def translatables(self):
         """See `IDistroSeriesSet`."""
@@ -1783,7 +1805,11 @@ class DistroSeriesSet:
 
     def queryByName(self, distribution, name, follow_aliases=False):
         """See `IDistroSeriesSet`."""
-        series = DistroSeries.selectOneBy(distribution=distribution, name=name)
+        series = (
+            IStore(DistroSeries)
+            .find(DistroSeries, distribution=distribution, name=name)
+            .one()
+        )
         if series is not None:
             return series
         if follow_aliases:
@@ -1795,8 +1821,10 @@ class DistroSeriesSet:
 
     def queryByVersion(self, distribution, version):
         """See `IDistroSeriesSet`."""
-        return DistroSeries.selectOneBy(
-            distribution=distribution, version=version
+        return (
+            IStore(DistroSeries)
+            .find(DistroSeries, distribution=distribution, version=version)
+            .one()
         )
 
     def _parseSuite(self, suite):
@@ -1841,23 +1869,21 @@ class DistroSeriesSet:
 
     def search(self, distribution=None, isreleased=None, orderBy=None):
         """See `IDistroSeriesSet`."""
-        where_clause = ""
+        clauses = []
         if distribution is not None:
-            where_clause += "distribution = %s" % sqlvalues(distribution.id)
+            clauses.append(DistroSeries.distribution == distribution)
         if isreleased is not None:
-            if where_clause:
-                where_clause += " AND "
             if isreleased:
                 # The query is filtered on released releases.
-                where_clause += "releasestatus in (%s, %s)" % sqlvalues(
-                    *ACTIVE_RELEASED_STATUSES
+                clauses.append(
+                    DistroSeries.status.is_in(ACTIVE_RELEASED_STATUSES)
                 )
             else:
                 # The query is filtered on unreleased releases.
-                where_clause += "releasestatus in (%s, %s, %s)" % sqlvalues(
-                    *ACTIVE_UNRELEASED_STATUSES
+                clauses.append(
+                    DistroSeries.status.is_in(ACTIVE_UNRELEASED_STATUSES)
                 )
+        rows = IStore(DistroSeries).find(DistroSeries, *clauses)
         if orderBy is not None:
-            return DistroSeries.select(where_clause, orderBy=orderBy)
-        else:
-            return DistroSeries.select(where_clause)
+            rows = rows.order_by(orderBy)
+        return rows
diff --git a/lib/lp/registry/model/distroseriesdifference.py b/lib/lp/registry/model/distroseriesdifference.py
index 75719fc..28859ba 100644
--- a/lib/lp/registry/model/distroseriesdifference.py
+++ b/lib/lp/registry/model/distroseriesdifference.py
@@ -98,7 +98,7 @@ def most_recent_publications(dsds, in_parent, statuses, match_version=False):
         tables=[Archive, DistroSeries],
         where=And(
             DistroSeries.id == series_col,
-            Archive.distributionID == DistroSeries.distributionID,
+            Archive.distributionID == DistroSeries.distribution_id,
             Archive.purpose == ArchivePurpose.PRIMARY,
         ),
     )
diff --git a/lib/lp/registry/model/sourcepackage.py b/lib/lp/registry/model/sourcepackage.py
index c15b371..cf3bb8e 100644
--- a/lib/lp/registry/model/sourcepackage.py
+++ b/lib/lp/registry/model/sourcepackage.py
@@ -667,7 +667,7 @@ class SourcePackage(
         """
             % sqlvalues(
                 self.sourcepackagename.id,
-                self.distroseries,
+                self.distroseries.id,
                 list(self.distribution.all_distro_archive_ids),
             )
         ]
@@ -877,19 +877,19 @@ class SourcePackage(
         We look for the source package task, followed by the distro source
         package, then the distroseries task, and lastly the distro task.
         """
-        sourcepackagenameID = self.sourcepackagename.id
-        seriesID = self.distroseries.id
-        distributionID = self.distroseries.distributionID
+        sourcepackagename_id = self.sourcepackagename.id
+        series_id = self.distroseries.id
+        distribution_id = self.distroseries.distribution_id
 
         def weight_function(bugtask):
-            if bugtask.sourcepackagename_id == sourcepackagenameID:
-                if bugtask.distroseries_id == seriesID:
+            if bugtask.sourcepackagename_id == sourcepackagename_id:
+                if bugtask.distroseries_id == series_id:
                     return OrderedBugTask(1, bugtask.id, bugtask)
-                elif bugtask.distribution_id == distributionID:
+                elif bugtask.distribution_id == distribution_id:
                     return OrderedBugTask(2, bugtask.id, bugtask)
-            elif bugtask.distroseries_id == seriesID:
+            elif bugtask.distroseries_id == series_id:
                 return OrderedBugTask(3, bugtask.id, bugtask)
-            elif bugtask.distribution_id == distributionID:
+            elif bugtask.distribution_id == distribution_id:
                 return OrderedBugTask(4, bugtask.id, bugtask)
             # Catch the default case, and where there is a task for the same
             # sourcepackage on a different distro.
diff --git a/lib/lp/registry/scripts/populate_distroseriesdiff.py b/lib/lp/registry/scripts/populate_distroseriesdiff.py
index a39d4bf..7847ee6 100644
--- a/lib/lp/registry/scripts/populate_distroseriesdiff.py
+++ b/lib/lp/registry/scripts/populate_distroseriesdiff.py
@@ -55,7 +55,7 @@ def compose_sql_find_latest_source_package_releases(distroseries):
     """
     parameters = {
         "active_status": quote(active_publishing_status),
-        "distroseries": quote(distroseries),
+        "distroseries": quote(distroseries.id),
         "main_archive": quote(distroseries.distribution.main_archive),
         "release_pocket": quote(PackagePublishingPocket.RELEASE),
     }
@@ -166,8 +166,8 @@ def compose_sql_populate_distroseriesdiff(
     :return: SQL query, as a string.
     """
     parameters = {
-        "derived_series": quote(derived_series),
-        "parent_series": quote(parent_series),
+        "derived_series": quote(derived_series.id),
+        "parent_series": quote(parent_series.id),
         "difference_type_expression": compose_sql_difference_type(),
         "needs_attention": quote(DistroSeriesDifferenceStatus.NEEDS_ATTENTION),
         "temp_table": quote_identifier(temp_table),
diff --git a/lib/lp/registry/vocabularies.py b/lib/lp/registry/vocabularies.py
index 955e975..d87766e 100644
--- a/lib/lp/registry/vocabularies.py
+++ b/lib/lp/registry/vocabularies.py
@@ -147,7 +147,6 @@ from lp.services.database import bulk
 from lp.services.database.decoratedresultset import DecoratedResultSet
 from lp.services.database.interfaces import IStore
 from lp.services.database.sqlbase import sqlvalues
-from lp.services.database.sqlobject import AND, CONTAINSSTRING, OR
 from lp.services.database.stormexpr import (
     RegexpMatch,
     WithMaterialized,
@@ -1342,11 +1341,11 @@ class ProductSeriesVocabulary(StormVocabularyBase):
         return result
 
 
-class FilteredDistroSeriesVocabulary(SQLObjectVocabularyBase):
+class FilteredDistroSeriesVocabulary(StormVocabularyBase):
     """Describes the series of a particular distribution."""
 
     _table = DistroSeries
-    _orderBy = "version"
+    _order_by = "version"
 
     def toTerm(self, obj):
         """See `IVocabulary`."""
@@ -1355,13 +1354,14 @@ class FilteredDistroSeriesVocabulary(SQLObjectVocabularyBase):
         )
 
     def __iter__(self):
-        kw = {}
-        if self._orderBy:
-            kw["orderBy"] = self._orderBy
         launchbag = getUtility(ILaunchBag)
         if launchbag.distribution:
             distribution = launchbag.distribution
-            series = self._table.selectBy(distributionID=distribution.id, **kw)
+            series = IStore(DistroSeries).find(
+                DistroSeries, distribution=distribution
+            )
+            if self._order_by:
+                series = series.order_by(self._order_by)
             for series in sorted(series, key=attrgetter("sortkey")):
                 yield self.toTerm(series)
 
@@ -1620,20 +1620,15 @@ class DistributionVocabulary(NamedSQLObjectVocabulary):
         return rows
 
 
-class DistroSeriesVocabulary(NamedSQLObjectVocabulary):
+class DistroSeriesVocabulary(NamedStormVocabulary):
     """All `IDistroSeries` objects vocabulary."""
 
     _table = DistroSeries
-    _orderBy = ["Distribution.displayname", "-DistroSeries.date_created"]
-    _clauseTables = ["Distribution"]
+    _order_by = [Distribution.display_name, Desc(DistroSeries.date_created)]
+    _clauses = [DistroSeries.distribution == Distribution.id]
 
     def __iter__(self):
-        series = self._table.select(
-            DistroSeries.q.distributionID == Distribution.q.id,
-            orderBy=self._orderBy,
-            clauseTables=self._clauseTables,
-        )
-        for series in sorted(series, key=attrgetter("sortkey")):
+        for series in sorted(self._entries, key=attrgetter("sortkey")):
             yield self.toTerm(series)
 
     @staticmethod
@@ -1672,18 +1667,19 @@ class DistroSeriesVocabulary(NamedSQLObjectVocabulary):
         if not query:
             return self.emptySelectResults()
 
-        query = six.ensure_text(query).lower()
-        objs = self._table.select(
-            AND(
-                Distribution.q.id == DistroSeries.q.distributionID,
-                OR(
-                    CONTAINSSTRING(Distribution.q.name, query),
-                    CONTAINSSTRING(DistroSeries.q.name, query),
+        query = query.lower()
+        return (
+            IStore(DistroSeries)
+            .find(
+                DistroSeries,
+                DistroSeries.distribution == Distribution.id,
+                Or(
+                    Distribution.name.contains_string(query),
+                    DistroSeries.name.contains_string(query),
                 ),
-            ),
-            orderBy=self._orderBy,
+            )
+            .order_by(self._order_by)
         )
-        return objs
 
 
 @implementer(IHugeVocabulary)
@@ -1792,10 +1788,10 @@ class DistroSeriesDerivationVocabulary(FilteredVocabularyBase):
             where.append(search)
         parent_distributions = list(
             IStore(DistroSeries).find(
-                parent.distributionID,
+                parent.distribution_id,
                 And(
-                    parent.distributionID != self.distribution.id,
-                    child.distributionID == self.distribution.id,
+                    parent.distribution_id != self.distribution.id,
+                    child.distribution_id == self.distribution.id,
                     child.id == DistroSeriesParent.derived_series_id,
                     parent.id == DistroSeriesParent.parent_series_id,
                 ),
@@ -1803,7 +1799,7 @@ class DistroSeriesDerivationVocabulary(FilteredVocabularyBase):
         )
         if parent_distributions != []:
             where.append(
-                DistroSeries.distributionID.is_in(parent_distributions)
+                DistroSeries.distribution_id.is_in(parent_distributions)
             )
             return self.find_terms(where)
         else:
diff --git a/lib/lp/scripts/harness.py b/lib/lp/scripts/harness.py
index d6dc0d0..b3b23aa 100644
--- a/lib/lp/scripts/harness.py
+++ b/lib/lp/scripts/harness.py
@@ -74,7 +74,7 @@ def _get_locals():
         # Do we really use these?  Are they worth carrying around?
         d = Distribution.get(1)
         p = Person.get(1)
-        ds = DistroSeries.get(1)
+        ds = store.get(DistroSeries, 1)
         prod = store.get(Product, 1)
         proj = store.get(ProjectGroup, 1)
         b2 = store.get(Bug, 2)
diff --git a/lib/lp/snappy/model/snapbuild.py b/lib/lp/snappy/model/snapbuild.py
index 174d586..afc3275 100644
--- a/lib/lp/snappy/model/snapbuild.py
+++ b/lib/lp/snappy/model/snapbuild.py
@@ -611,7 +611,7 @@ class SnapBuildSet(SpecificBuildFarmJobSourceMixin):
         distroseries = load_related(
             DistroSeries, distroarchseries, ["distroseries_id"]
         )
-        load_related(Distribution, distroseries, ["distributionID"])
+        load_related(Distribution, distroseries, ["distribution_id"])
         snaps = load_related(Snap, builds, ["snap_id"])
         getUtility(ISnapSet).preloadDataForSnaps(snaps)
         snapbuild_ids = set(map(attrgetter("id"), builds))
diff --git a/lib/lp/snappy/vocabularies.py b/lib/lp/snappy/vocabularies.py
index a7625d1..32cfaea 100644
--- a/lib/lp/snappy/vocabularies.py
+++ b/lib/lp/snappy/vocabularies.py
@@ -118,7 +118,7 @@ class SnappyDistroSeriesVocabulary(StormVocabularyBase):
             DistroSeries,
             SnappyDistroSeries.distro_series_id == DistroSeries.id,
         ),
-        LeftJoin(Distribution, DistroSeries.distributionID == Distribution.id),
+        LeftJoin(Distribution, DistroSeries.distribution == Distribution.id),
         SnappySeries,
     ]
     _clauses = [
diff --git a/lib/lp/soyuz/doc/gina-multiple-arch.rst b/lib/lp/soyuz/doc/gina-multiple-arch.rst
index 2c9f06b..d36a2fe 100644
--- a/lib/lp/soyuz/doc/gina-multiple-arch.rst
+++ b/lib/lp/soyuz/doc/gina-multiple-arch.rst
@@ -60,8 +60,10 @@ Create a distribution series and an arch series for dapper:
 Check it was properly created and create its DistroArchSeriess.
 
     >>> from lp.registry.model.distroseries import DistroSeries
-    >>> dapper = DistroSeries.selectOneBy(
-    ...     name="dapper", distributionID=ubuntu.id
+    >>> dapper = (
+    ...     IStore(DistroSeries)
+    ...     .find(DistroSeries, name="dapper", distribution=ubuntu)
+    ...     .one()
     ... )
     >>> processor = getUtility(IProcessorSet).getByName("386")
     >>> dar = dapper.newArch(
diff --git a/lib/lp/soyuz/doc/soyuz-set-of-uploads.rst b/lib/lp/soyuz/doc/soyuz-set-of-uploads.rst
index 1ba2b35..0355122 100644
--- a/lib/lp/soyuz/doc/soyuz-set-of-uploads.rst
+++ b/lib/lp/soyuz/doc/soyuz-set-of-uploads.rst
@@ -643,7 +643,7 @@ Set ubuntutest/breezy to 'experimental' state again to not affect the
 rest of the test:
 
     >>> breezy.status = SeriesStatus.EXPERIMENTAL
-    >>> breezy.syncUpdate()
+    >>> IStore(breezy).flush()
 
 
 Regression test for bug 54039. Currently must be here, see bug 54158.
diff --git a/lib/lp/soyuz/model/binarypackagebuild.py b/lib/lp/soyuz/model/binarypackagebuild.py
index 202265f..ca82a8e 100644
--- a/lib/lp/soyuz/model/binarypackagebuild.py
+++ b/lib/lp/soyuz/model/binarypackagebuild.py
@@ -944,7 +944,7 @@ class BinaryPackageBuildSet(SpecificBuildFarmJobSourceMixin):
         archives = load_related(Archive, builds, ["archive_id"])
         load_related(Person, archives, ["ownerID"])
         distroseries = load_related(DistroSeries, das, ["distroseries_id"])
-        load_related(Distribution, distroseries, ["distributionID"])
+        load_related(Distribution, distroseries, ["distribution_id"])
 
     def getByBuildFarmJobs(self, build_farm_jobs):
         """See `ISpecificBuildFarmJobSource`."""
diff --git a/lib/lp/soyuz/model/initializedistroseriesjob.py b/lib/lp/soyuz/model/initializedistroseriesjob.py
index 48a30eb..e487713 100644
--- a/lib/lp/soyuz/model/initializedistroseriesjob.py
+++ b/lib/lp/soyuz/model/initializedistroseriesjob.py
@@ -141,7 +141,7 @@ class InitializeDistroSeriesJob(DistributionJobDerived):
         parts += ", parent[overlay?/pockets/components]: "
         parents = []
         for i in range(len(self.overlays)):
-            series = DistroSeries.get(self.parents[i])
+            series = IStore(DistroSeries).get(DistroSeries, self.parents[i])
             parents.append(
                 "%s[%s/%s/%s]"
                 % (
diff --git a/lib/lp/soyuz/model/packagecloner.py b/lib/lp/soyuz/model/packagecloner.py
index 659345d..15029b4 100644
--- a/lib/lp/soyuz/model/packagecloner.py
+++ b/lib/lp/soyuz/model/packagecloner.py
@@ -229,7 +229,7 @@ class PackageCloner:
             WHERE mcd.obsoleted = True OR mcd.missing = True
             """
             % sqlvalues(
-                destination.distroseries,
+                destination.distroseries.id,
                 destination.archive,
                 UTC_NOW,
                 UTC_NOW,
@@ -294,7 +294,7 @@ class PackageCloner:
             origin.archive,
             PackagePublishingStatus.PENDING,
             PackagePublishingStatus.PUBLISHED,
-            origin.distroseries,
+            origin.distroseries.id,
             origin.pocket,
         )
 
@@ -337,7 +337,7 @@ class PackageCloner:
             origin.archive,
             PackagePublishingStatus.PENDING,
             PackagePublishingStatus.PUBLISHED,
-            origin.distroseries,
+            origin.distroseries.id,
             origin.pocket,
         )
 
@@ -417,7 +417,7 @@ class PackageCloner:
             destination.archive,
             PackagePublishingStatus.PENDING,
             PackagePublishingStatus.PUBLISHED,
-            destination.distroseries,
+            destination.distroseries.id,
             destination.pocket,
         )
 
@@ -464,12 +464,12 @@ class PackageCloner:
                 spph.pocket = %s AND
                 spph.archive = %s
             """ % sqlvalues(
-            destination.distroseries,
+            destination.distroseries.id,
             destination.archive,
             UTC_NOW,
             UTC_NOW,
             destination.pocket,
-            origin.distroseries,
+            origin.distroseries.id,
             PackagePublishingStatus.PENDING,
             PackagePublishingStatus.PUBLISHED,
             origin.pocket,
diff --git a/lib/lp/soyuz/model/packagecopyjob.py b/lib/lp/soyuz/model/packagecopyjob.py
index fa87145..d441a99 100644
--- a/lib/lp/soyuz/model/packagecopyjob.py
+++ b/lib/lp/soyuz/model/packagecopyjob.py
@@ -878,7 +878,7 @@ class PlainPackageCopyJob(PackageCopyJobDerived):
         return [
             dsd
             for dsd in candidates
-            if dsd.parent_series.distributionID == source_distro_id
+            if dsd.parent_series.distribution_id == source_distro_id
         ]
 
     def reportFailure(self, message):
diff --git a/lib/lp/soyuz/scripts/gina/handlers.py b/lib/lp/soyuz/scripts/gina/handlers.py
index 8d07ea7..60b047c 100644
--- a/lib/lp/soyuz/scripts/gina/handlers.py
+++ b/lib/lp/soyuz/scripts/gina/handlers.py
@@ -245,7 +245,11 @@ class ImporterHandler:
 
     def _get_distroseries(self, name):
         """Return the distroseries database object by name."""
-        dr = DistroSeries.selectOneBy(name=name, distributionID=self.distro.id)
+        dr = (
+            IStore(DistroSeries)
+            .find(DistroSeries, name=name, distribution=self.distro)
+            .one()
+        )
         if not dr:
             raise DataSetupError("Error finding distroseries %r" % name)
         return dr
diff --git a/lib/lp/soyuz/scripts/initialize_distroseries.py b/lib/lp/soyuz/scripts/initialize_distroseries.py
index 8e76922..bcb6f28 100644
--- a/lib/lp/soyuz/scripts/initialize_distroseries.py
+++ b/lib/lp/soyuz/scripts/initialize_distroseries.py
@@ -473,7 +473,7 @@ class InitializeDistroSeries:
             GROUP BY processor, architecturetag
             """
             % (
-                sqlvalues(self.distroseries, self.distroseries.owner)
+                sqlvalues(self.distroseries.id, self.distroseries.owner.id)
                 + (das_filter,)
             )
         )
diff --git a/lib/lp/soyuz/vocabularies.py b/lib/lp/soyuz/vocabularies.py
index 2ce2ac7..1b640b8 100644
--- a/lib/lp/soyuz/vocabularies.py
+++ b/lib/lp/soyuz/vocabularies.py
@@ -69,7 +69,7 @@ class FilteredDistroArchSeriesVocabulary(StormVocabularyBase):
                 .find(
                     self._table,
                     DistroSeries.id == DistroArchSeries.distroseries_id,
-                    DistroSeries.distributionID == distribution.id,
+                    DistroSeries.distribution == distribution,
                 )
                 .order_by(*self._orderBy)
             )
diff --git a/lib/lp/translations/doc/distroseries-translations-copy.rst b/lib/lp/translations/doc/distroseries-translations-copy.rst
index bc3df4f..4aa591c 100644
--- a/lib/lp/translations/doc/distroseries-translations-copy.rst
+++ b/lib/lp/translations/doc/distroseries-translations-copy.rst
@@ -201,7 +201,8 @@ set.
 
     >>> transaction.abort()
     >>> from lp.registry.model.distroseries import DistroSeries
-    >>> darty = DistroSeries.get(darty_id)
+    >>> from lp.services.database.interfaces import IStore
+    >>> darty = IStore(DistroSeries).get(DistroSeries, darty_id)
     >>> darty.defer_translation_imports
     False
     >>> darty.hide_all_translations
@@ -211,7 +212,7 @@ It succeeds, however, when we pass the --force option.  The script then
 sets the defer_translation_imports flag itself before copying.
 
     >>> transaction.abort()
-    >>> darty = DistroSeries.get(darty_id)
+    >>> darty = IStore(DistroSeries).get(DistroSeries, darty_id)
     >>> returnvalue, output, error_output = run_script(
     ...     "scripts/copy-distroseries-translations.py",
     ...     ["--distribution=foobuntu", "--series=darty", "--force"],
@@ -243,7 +244,7 @@ After completing, the script restores the defer_translation_imports
 flag to its previous value (off).
 
     >>> transaction.abort()
-    >>> darty = DistroSeries.get(darty_id)
+    >>> darty = IStore(DistroSeries).get(DistroSeries, darty_id)
     >>> darty.defer_translation_imports
     False
     >>> darty.hide_all_translations
@@ -331,7 +332,7 @@ for package2, and template3 is inactive, so they're both skipped.
     >>> returnvalue
     0
     >>> transaction.abort()
-    >>> lumpy = DistroSeries.get(lumpy_id)
+    >>> lumpy = IStore(DistroSeries).get(DistroSeries, lumpy_id)
     >>> len(getUtility(IPOTemplateSet).getSubset(distroseries=lumpy))
     0
 
@@ -354,7 +355,7 @@ for package2, and template3 is inactive, so they're both skipped.
     >>> returnvalue
     0
     >>> transaction.abort()
-    >>> lumpy = DistroSeries.get(lumpy_id)
+    >>> lumpy = IStore(DistroSeries).get(DistroSeries, lumpy_id)
     >>> for pot in getUtility(IPOTemplateSet).getSubset(distroseries=lumpy):
     ...     print(pot.name)
     ...
diff --git a/lib/lp/translations/doc/translationimportqueue.rst b/lib/lp/translations/doc/translationimportqueue.rst
index 29dabee..aa79840 100644
--- a/lib/lp/translations/doc/translationimportqueue.rst
+++ b/lib/lp/translations/doc/translationimportqueue.rst
@@ -111,7 +111,7 @@ this IPOFile is located ('po/')
 Now let's try the same against the evolution sourcepackage that only has an
 IPOTemplate.
 
-    >>> hoary_distroseries = DistroSeries.get(3)
+    >>> hoary_distroseries = IStore(DistroSeries).get(DistroSeries, 3)
     >>> evolution_sourcepackagename = IStore(SourcePackageName).get(
     ...     SourcePackageName, 9
     ... )
diff --git a/lib/lp/translations/model/distroseries_translations_copy.py b/lib/lp/translations/model/distroseries_translations_copy.py
index d66474b..bd7de81 100644
--- a/lib/lp/translations/model/distroseries_translations_copy.py
+++ b/lib/lp/translations/model/distroseries_translations_copy.py
@@ -123,7 +123,7 @@ def copy_active_translations(
 
     # Copy relevant POTemplates from existing series into a holding table,
     # complete with their original id fields.
-    where = "distroseries = %s AND iscurrent" % quote(source)
+    where = "distroseries = %s AND iscurrent" % quote(source.id)
     if sourcepackagenames is not None:
         if not sourcepackagenames:
             where += " AND false"
@@ -137,7 +137,7 @@ def copy_active_translations(
                 SELECT sourcepackagename FROM potemplate
                 WHERE distroseries = %s)
             """ % quote(
-            target
+            target.id
         )
     copier.extract("potemplate", [], where)
 
@@ -156,7 +156,7 @@ def copy_active_translations(
                 timezone('UTC'::text,
                     ('now'::text)::timestamp(6) with time zone)
     """
-        % (copier.getHoldingTableName("potemplate"), quote(target))
+        % (copier.getHoldingTableName("potemplate"), quote(target.id))
     )
 
     # Copy each TranslationTemplateItem whose template we copied, and let
diff --git a/lib/lp/translations/model/potemplate.py b/lib/lp/translations/model/potemplate.py
index 22fa91a..87e79d5 100644
--- a/lib/lp/translations/model/potemplate.py
+++ b/lib/lp/translations/model/potemplate.py
@@ -1691,7 +1691,7 @@ class POTemplateSharingSubset:
             Location,
             LeftJoin(
                 DistroSeries,
-                DistroSeries.distributionID == Location.distribution_id,
+                DistroSeries.distribution_id == Location.distribution_id,
             ),
             LeftJoin(
                 ProductSeries, ProductSeries.product_id == Location.product_id
diff --git a/lib/lp/translations/model/translationimportqueue.py b/lib/lp/translations/model/translationimportqueue.py
index af10e15..f89b2c3 100644
--- a/lib/lp/translations/model/translationimportqueue.py
+++ b/lib/lp/translations/model/translationimportqueue.py
@@ -964,7 +964,7 @@ def list_distroseries_request_targets(status_condition):
     distroseries = IStore(DistroSeries).find(
         DistroSeries,
         DistroSeries.defer_translation_imports == False,
-        Distribution.id == DistroSeries.distributionID,
+        Distribution.id == DistroSeries.distribution_id,
         DistroSeries.id.is_in(
             Select(
                 TranslationImportQueueEntry.distroseries_id,
diff --git a/lib/lp/translations/model/translationsperson.py b/lib/lp/translations/model/translationsperson.py
index 3d80d12..715ba35 100644
--- a/lib/lp/translations/model/translationsperson.py
+++ b/lib/lp/translations/model/translationsperson.py
@@ -311,10 +311,10 @@ class TranslationsPerson:
                     Join(
                         Distribution,
                         And(
-                            Distribution.id == DistroSeries.distributionID,
+                            Distribution.id == DistroSeries.distribution_id,
                             Distribution.translations_usage
                             == ServiceUsage.LAUNCHPAD,
-                            Distribution.translation_focusID
+                            Distribution.translation_focus_id
                             == DistroSeries.id,
                         ),
                     ),
@@ -397,9 +397,9 @@ class TranslationsPerson:
         # If there's a DistroSeries, it should be the distro's
         # translation focus.
         distrojoin_conditions = And(
-            Distribution.id == DistroSeries.distributionID,
+            Distribution.id == DistroSeries.distribution_id,
             Distribution.translations_usage == ServiceUsage.LAUNCHPAD,
-            Distribution.translation_focusID == DistroSeries.id,
+            Distribution.translation_focus_id == DistroSeries.id,
         )
 
         DistroJoin = LeftJoin(Distribution, distrojoin_conditions)
diff --git a/lib/lp/translations/scripts/language_pack.py b/lib/lp/translations/scripts/language_pack.py
index 2da785d..41c2f19 100644
--- a/lib/lp/translations/scripts/language_pack.py
+++ b/lib/lp/translations/scripts/language_pack.py
@@ -15,11 +15,13 @@ import tempfile
 from shutil import copyfileobj
 
 import transaction
+from storm.expr import Is
 from storm.store import Store
 from zope.component import getUtility
 
 from lp.registry.interfaces.distribution import IDistributionSet
-from lp.services.database.sqlbase import cursor, sqlvalues
+from lp.registry.model.sourcepackagename import SourcePackageName
+from lp.services.database.interfaces import IStore
 from lp.services.librarian.interfaces.client import (
     ILibrarianClient,
     UploadFailed,
@@ -28,6 +30,7 @@ from lp.services.tarfile_helpers import LaunchpadWriteTarFile
 from lp.translations.enums import LanguagePackType
 from lp.translations.interfaces.languagepack import ILanguagePackSet
 from lp.translations.interfaces.vpoexport import IVPOExportSet
+from lp.translations.model.potemplate import POTemplate
 
 
 def iter_sourcepackage_translationdomain_mapping(series):
@@ -37,22 +40,12 @@ def iter_sourcepackage_translationdomain_mapping(series):
     With the output of this method we can know the translationdomains that
     a sourcepackage has.
     """
-    cur = cursor()
-    cur.execute(
-        """
-        SELECT SourcePackageName.name, POTemplate.translation_domain
-        FROM
-            SourcePackageName
-            JOIN POTemplate ON
-                POTemplate.sourcepackagename = SourcePackageName.id AND
-                POTemplate.distroseries = %s AND
-                POTemplate.languagepack = TRUE
-        ORDER BY SourcePackageName.name, POTemplate.translation_domain
-        """
-        % sqlvalues(series)
-    )
-
-    yield from cur.fetchall()
+    yield from IStore(SourcePackageName).find(
+        (SourcePackageName.name, POTemplate.translation_domain),
+        POTemplate.sourcepackagename == SourcePackageName.id,
+        POTemplate.distroseries == series,
+        Is(POTemplate.languagepack, True),
+    ).order_by(SourcePackageName.name, POTemplate.translation_domain)
 
 
 def export(distroseries, component, update, force_utf8, logger):
diff --git a/lib/lp/translations/scripts/scrub_pofiletranslator.py b/lib/lp/translations/scripts/scrub_pofiletranslator.py
index 99048e0..ee45697 100644
--- a/lib/lp/translations/scripts/scrub_pofiletranslator.py
+++ b/lib/lp/translations/scripts/scrub_pofiletranslator.py
@@ -252,7 +252,7 @@ def preload_work_items(work_items):
     load_related(Language, pofiles, ["language_id"])
     templates = load_related(POTemplate, pofiles, ["potemplate_id"])
     distroseries = load_related(DistroSeries, templates, ["distroseries_id"])
-    load_related(Distribution, distroseries, ["distributionID"])
+    load_related(Distribution, distroseries, ["distribution_id"])
     productseries = load_related(
         ProductSeries, templates, ["productseries_id"]
     )
diff --git a/lib/lp/translations/tests/test_autoapproval.py b/lib/lp/translations/tests/test_autoapproval.py
index 94cfb07..ef4c11f 100644
--- a/lib/lp/translations/tests/test_autoapproval.py
+++ b/lib/lp/translations/tests/test_autoapproval.py
@@ -1217,7 +1217,7 @@ class TestCleanup(TestCaseWithFactory, GardenerDbUserMixin):
         self.assertTrue(self._exists(entry_id))
 
         entry.distroseries.status = SeriesStatus.OBSOLETE
-        entry.distroseries.syncUpdate()
+        self.store.flush()
 
         self.becomeTheGardener()
         self.queue._cleanUpObsoleteDistroEntries(self.store)