Skip to content

Commit

Permalink
Looking up foreign keys now avoids db access if possible
Browse files Browse the repository at this point in the history
  • Loading branch information
gvx committed Feb 6, 2021
1 parent b858970 commit ebfb399
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
9 changes: 9 additions & 0 deletions tests/test_relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,12 @@ def test_relation_6(connection):
Child7(parent=p).insert()
Child7(parent=p).insert()
assert len(p.children) == 0


def test_relation_7(connection):
p = Parent()
p.insert()
Child(parent=p).insert()
Parent.del_object(p)
c, = Child
assert len(c.parent.children) == 1
22 changes: 16 additions & 6 deletions wurm/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from weakref import WeakValueDictionary

from .typemaps import (to_stored, Primary, is_primary, unwrap_type,
is_unique)
from .queries import Query
is_unique, columns_for)
from .queries import Query, decode_row
from .connection import execute
from . import sql

Expand All @@ -28,10 +28,10 @@ def indexes(fields):
if is_unique(value))

def primary_key_columns(item):
for fieldname, ty in item.__fields_info__.items():
if fieldname in item.__primary_key__:
yield from to_stored(fieldname, ty,
getattr(item, fieldname)).values()
info = item.__fields_info__
for fieldname in item.__primary_key__:
yield from to_stored(fieldname, info[fieldname],
getattr(item, fieldname)).values()

class relation:
"""Describe a relationship between two tables.
Expand Down Expand Up @@ -156,6 +156,16 @@ def query(self, **kwargs):
return Query(self, kwargs)
def get_object(self, pk, values):
if pk not in self.__id_map__:
if values is None:
info = self.__fields_info__
params = {name: value for field in self.__primary_key__
for name, value
in zip(columns_for(field, info[field]), pk)}
comparisons = ' and '.join(f'{column}=:{column}'
for column in params)
params['_limit_'] = 1
row = execute(sql.select(self, comparisons, True), params).fetchone()
return decode_row(self, row)
if 'rowid' in values:
rowid = values.pop('rowid')
else:
Expand Down
3 changes: 1 addition & 2 deletions wurm/typemaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,10 @@ def from_stored(stored_tuple, python_type):
if all(v is None for v in stored_tuple):
return None
from .tables import BaseTable
from .queries import Query
if issubclass(python_type, BaseTable):
# FIXME: this is problematic for recursive foreign keys
# not to mention the n + 1 problem
return Query(python_type, dict(zip(python_type.__primary_key__, stored_tuple))).one()
return python_type.get_object(stored_tuple, None)
return TYPE_MAPPING[python_type].decode(*stored_tuple)

def sql_type_for(fieldname, python_type):
Expand Down

0 comments on commit ebfb399

Please sign in to comment.