fix: occasional errors when loading package details

Fixes errors that might occur when loading the package details page.

Problem:
We are querying a list of "Required by" packages.
This list is loaded with all details for a "PackageDependency" record.

Now we also have a reference to some attributes from the
related package (PackageDependency.Package.xxx)

This will effectively trigger the ORM to run another query (lazyload),
to fetch the missing Package data (for each PackageDependency record).

At that point it might have happened that a referenced package
got deleted / updated so that we can't retrieve this data anymore and
our dep.Package object is "None"

Fix:
We can force our query to include Package data right away.
Thus we can avoid running a separate query (per "required by"...)

As a side-effect we get better performance.

Signed-off-by: moson-mo <mo-son@mailbox.org>
This commit is contained in:
moson-mo 2023-01-25 19:24:57 +01:00
parent 6c9be9eb97
commit becce1aac4
No known key found for this signature in database
GPG key ID: 4A4760AB4EE15296
2 changed files with 21 additions and 0 deletions

View file

@ -217,6 +217,7 @@ def pkg_required(pkgname: str, provides: list[str]) -> list[PackageDependency]:
query = (
db.query(PackageDependency)
.join(Package)
.options(orm.contains_eager(PackageDependency.Package))
.filter(PackageDependency.DepName.in_(targets))
.order_by(Package.Name.asc())
)

View file

@ -4,9 +4,11 @@ from fastapi.testclient import TestClient
from aurweb import asgi, config, db, time
from aurweb.aur_redis import kill_redis
from aurweb.models.account_type import USER_ID
from aurweb.models.dependency_type import DEPENDS_ID
from aurweb.models.official_provider import OFFICIAL_BASE, OfficialProvider
from aurweb.models.package import Package
from aurweb.models.package_base import PackageBase
from aurweb.models.package_dependency import PackageDependency
from aurweb.models.package_notification import PackageNotification
from aurweb.models.package_source import PackageSource
from aurweb.models.package_vote import PackageVote
@ -129,3 +131,21 @@ def test_source_uri_unnamed_uri(package: Package):
)
file, uri = util.source_uri(pkgsrc)
assert (file, uri) == (URL, URL)
def test_pkg_required(package: Package):
with db.begin():
db.create(
PackageDependency,
Package=package,
DepName="test",
DepTypeID=DEPENDS_ID,
)
# We want to make sure "Package" data is included
# to avoid lazy-loading the information for each dependency
qry = util.pkg_required("test", list())
assert "Packages_ID" in str(qry)
# We should have 1 record
assert qry.count() == 1