loosen type Mapper args, add more Database tests
This commit is contained in:
parent
b369428eb3
commit
1f89f0dee8
@ -56,7 +56,7 @@ class RelationalAccessor[R: Relation](Accessor[R]):
|
||||
connection,
|
||||
text: str
|
||||
):
|
||||
connection.exec
|
||||
#connection.exec
|
||||
raise NotImplementedError
|
||||
|
||||
def select(
|
||||
@ -104,11 +104,17 @@ class SQLAccessor(RelationalAccessor[SQLTable]):
|
||||
mappings=False,
|
||||
include_cols=False,
|
||||
):
|
||||
res_method = utils.db.sa_exec_dicts
|
||||
if mappings:
|
||||
res_method = utils.db.sa_exec_mappings
|
||||
res = SQLEngine.execute(
|
||||
connection,
|
||||
sql,
|
||||
bind_params=bind_params,
|
||||
include_cols=include_cols
|
||||
)
|
||||
|
||||
return res_method(self.database.engine, sa.text(sql), bind_params=bind_params, include_cols=include_cols)
|
||||
if mappings:
|
||||
return res.mappings().all()
|
||||
else:
|
||||
return self.result_dicts(res)
|
||||
|
||||
def select(
|
||||
self,
|
||||
|
@ -37,13 +37,13 @@ class Collector[C: Component]:
|
||||
def __init__(self, schema: Schema[C]):
|
||||
self.schema = schema
|
||||
|
||||
self._inserts = defaultdict(lambda: defaultdict(list))
|
||||
self._inserts = {}
|
||||
|
||||
@property
|
||||
def inserts(self):
|
||||
return self._inserts_from_receipts()
|
||||
|
||||
def _inserts_from_receipts(self, receipts: list=None, pop=False):
|
||||
def _inserts_from_receipts(self, receipts: list[str]|None=None, pop=False):
|
||||
'''
|
||||
Group up added inserts by Component, often to be used directly for bulk insertion.
|
||||
Optionally provide a list of `receipts` to group up only the corresponding subset of
|
||||
@ -104,7 +104,7 @@ class Collector[C: Component]:
|
||||
|
||||
return receipt
|
||||
|
||||
def collect_inserts(self, receipts=None):
|
||||
def collect_inserts(self, receipts:list[str]|None=None):
|
||||
'''
|
||||
Collect insert-ready dictionaries for the core primitive schema. This method is
|
||||
effectively a light wrapper around the File and Note-based collection logic
|
||||
|
@ -157,17 +157,25 @@ class Mapper[C: Component]:
|
||||
|
||||
self.attach(_type, attr_comp, coll_groups=coll_groups)
|
||||
|
||||
def get_attribute_comp(
|
||||
def get_attr_comp(
|
||||
self,
|
||||
type_ref: type[CO3]
|
||||
co3_ref: CO3 | type[CO3]
|
||||
) -> C | None:
|
||||
type_ref = co3_ref
|
||||
if isinstance(co3_ref, CO3):
|
||||
type_ref = co3_ref.__class__
|
||||
|
||||
return self.attribute_comps.get(type_ref, None)
|
||||
|
||||
def get_collation_comp(
|
||||
def get_coll_comp(
|
||||
self,
|
||||
type_ref: type[CO3],
|
||||
co3_ref: CO3 | type[CO3],
|
||||
group=str | None,
|
||||
) -> C | None:
|
||||
type_ref = co3_ref
|
||||
if isinstance(co3_ref, CO3):
|
||||
type_ref = co3_ref.__class__
|
||||
|
||||
return self.collation_groups.get(type_ref, {}).get(group, None)
|
||||
|
||||
def collect(
|
||||
@ -201,7 +209,7 @@ class Mapper[C: Component]:
|
||||
|
||||
receipts = []
|
||||
for _cls in reversed(obj.__class__.__mro__[:-2]):
|
||||
attribute_component = self.get_attribute_comp(_cls)
|
||||
attribute_component = self.get_attr_comp(_cls)
|
||||
|
||||
# require an attribute component for type consideration
|
||||
if attribute_component is None:
|
||||
@ -222,7 +230,7 @@ class Mapper[C: Component]:
|
||||
|
||||
_, action_groups = obj.action_registry.get(action_key, (None, []))
|
||||
for action_group in action_groups:
|
||||
collation_component = self.get_collation_comp(_cls, group=action_group)
|
||||
collation_component = self.get_coll_comp(_cls, group=action_group)
|
||||
|
||||
if collation_component is None:
|
||||
continue
|
||||
@ -331,7 +339,7 @@ class ComposableMapper[C: ComposableComponent](Mapper[C]):
|
||||
|
||||
def compose(
|
||||
self,
|
||||
obj: CO3 | type[CO3],
|
||||
co3_ref: CO3 | type[CO3],
|
||||
action_groups: list[str] | None = None,
|
||||
*compose_args,
|
||||
**compose_kwargs,
|
||||
@ -348,13 +356,13 @@ class ComposableMapper[C: ComposableComponent](Mapper[C]):
|
||||
Parameters:
|
||||
obj: either a CO3 instance or a type reference
|
||||
'''
|
||||
class_ref = obj
|
||||
if isinstance(obj, CO3):
|
||||
class_ref = obj.__class__
|
||||
type_ref = co3_ref
|
||||
if isinstance(co3_ref, CO3):
|
||||
type_ref = co3_ref.__class__
|
||||
|
||||
attr_comp_agg = None
|
||||
for _cls in reversed(class_ref.__mro__[:-2]):
|
||||
attr_comp = self.get_attribute_comp(_cls)
|
||||
for _cls in reversed(type_ref.__mro__[:-2]):
|
||||
attr_comp = self.get_attr_comp(_cls)
|
||||
|
||||
# require an attribute component for type consideration
|
||||
if attr_comp is None:
|
||||
@ -364,7 +372,7 @@ class ComposableMapper[C: ComposableComponent](Mapper[C]):
|
||||
coll_comp_agg = attr_comp
|
||||
if action_groups is not None:
|
||||
for action_group in action_groups:
|
||||
coll_comp = self.get_collation_comp(_cls, group=action_group)
|
||||
coll_comp = self.get_coll_comp(_cls, group=action_group)
|
||||
|
||||
if coll_comp is None:
|
||||
continue
|
||||
|
@ -7,14 +7,14 @@ def test_mapper_getters():
|
||||
veg_comp = veg.vegetable_schema.get_component('vegetable')
|
||||
tom_comp = veg.vegetable_schema.get_component('tomato')
|
||||
|
||||
assert veg.vegetable_mapper.get_attribute_comp(veg.Vegetable) is veg_comp
|
||||
assert veg.vegetable_mapper.get_attribute_comp(veg.Tomato) is tom_comp
|
||||
assert veg.vegetable_mapper.get_attr_comp(veg.Vegetable) is veg_comp
|
||||
assert veg.vegetable_mapper.get_attr_comp(veg.Tomato) is tom_comp
|
||||
|
||||
tom_aging = veg.vegetable_schema.get_component('tomato_aging_states')
|
||||
tom_cooking = veg.vegetable_schema.get_component('tomato_cooking_states')
|
||||
|
||||
assert veg.vegetable_mapper.get_collation_comp(veg.Tomato, 'aging') is tom_aging
|
||||
assert veg.vegetable_mapper.get_collation_comp(veg.Tomato, 'cooking') is tom_cooking
|
||||
assert veg.vegetable_mapper.get_coll_comp(veg.Tomato, 'aging') is tom_aging
|
||||
assert veg.vegetable_mapper.get_coll_comp(veg.Tomato, 'cooking') is tom_cooking
|
||||
|
||||
def test_mapper_attach():
|
||||
assert veg.vegetable_mapper.attach(
|
||||
|
@ -20,6 +20,24 @@ def test_database_insert():
|
||||
tomato = veg.Tomato('t1', 5)
|
||||
veg.vegetable_mapper.collect(tomato)
|
||||
|
||||
# test instance as arg
|
||||
tom_comp = veg.vegetable_mapper.get_attr_comp(tomato)
|
||||
|
||||
inserts = veg.vegetable_mapper.collector.collect_inserts()
|
||||
tom_inserts = inserts.get(tom_comp)
|
||||
assert tom_inserts is not None
|
||||
|
||||
with db.engine.connect() as connection:
|
||||
assert db.manager.insert(
|
||||
connection,
|
||||
tom_comp,
|
||||
tom_inserts,
|
||||
) is not None
|
||||
|
||||
def test_database_insert_many():
|
||||
tomato = veg.Tomato('t2', 5)
|
||||
veg.vegetable_mapper.collect(tomato)
|
||||
|
||||
with db.engine.connect() as connection:
|
||||
assert db.manager.insert_many(
|
||||
connection,
|
||||
|
@ -7,14 +7,14 @@ def test_mapper_getters():
|
||||
veg_comp = veg.vegetable_schema.get_component('vegetable')
|
||||
tom_comp = veg.vegetable_schema.get_component('tomato')
|
||||
|
||||
assert veg.vegetable_mapper.get_attribute_comp(veg.Vegetable) is veg_comp
|
||||
assert veg.vegetable_mapper.get_attribute_comp(veg.Tomato) is tom_comp
|
||||
assert veg.vegetable_mapper.get_attr_comp(veg.Vegetable) is veg_comp
|
||||
assert veg.vegetable_mapper.get_attr_comp(veg.Tomato) is tom_comp
|
||||
|
||||
tom_aging = veg.vegetable_schema.get_component('tomato_aging_states')
|
||||
tom_cooking = veg.vegetable_schema.get_component('tomato_cooking_states')
|
||||
|
||||
assert veg.vegetable_mapper.get_collation_comp(veg.Tomato, 'aging') is tom_aging
|
||||
assert veg.vegetable_mapper.get_collation_comp(veg.Tomato, 'cooking') is tom_cooking
|
||||
assert veg.vegetable_mapper.get_coll_comp(veg.Tomato, 'aging') is tom_aging
|
||||
assert veg.vegetable_mapper.get_coll_comp(veg.Tomato, 'cooking') is tom_cooking
|
||||
|
||||
def test_mapper_attach():
|
||||
assert veg.vegetable_mapper.attach(
|
||||
|
Loading…
Reference in New Issue
Block a user