datajoint-python icon indicating copy to clipboard operation
datajoint-python copied to clipboard

Error when populating from two parent table with a shared secondary attribute

Open dimitri-yatsenko opened this issue 3 years ago • 0 comments
trafficstars

Code to reproduce the error in datajoint version 0.13.3

import datajoint as dj

schema = dj.Schema('test')


@schema
class A(dj.Lookup):
    definition = """
    a : int
    ---
    q : int
    """
    contents = ((1, 1), (2, 3), (3, 2))

@schema
class B(dj.Lookup):
    definition = """
    b : int
    ---
    q : int
    """
    contents = ((1, 1), (2, 3), (3, 2))
    
@schema
class C(dj.Computed):
    definition = """
    -> A
    -> B    
    """
    
    def make(self, key):
        print(key)
       
C.populate()

Error message:

~/dev/datajoint-python/datajoint/condition.py in assert_join_compatibility(expr1, expr2)
     63     if not isinstance(expr1, U) and not isinstance(expr2, U):  # dj.U is always compatible
     64         try:
---> 65             raise DataJointError(
     66                 "Cannot join query expressions on dependent attribute `%s`" % next(
     67                     r for r in set(expr1.heading.secondary_attributes).intersection(

DataJointError: Cannot join query expressions on dependent attribute `q`

Solution

This is indeed a bug. The default key_source should have projected out the secondary attributes. Fixing..

Workaround

As a temporary solution, you need to override the key_source to project out the shared secondary attribute from one of the parent tables:

@schema
class C(dj.Computed):
    definition = """
    -> A
    -> B    
    """
    
    @property
    def key_source(self):
        return A.proj() * B
    
    def make(self, key):
        print(key)

dimitri-yatsenko avatar Jan 10 '22 01:01 dimitri-yatsenko