@@ -146,7 +146,7 @@ def __init__(
146146 password = jwt_payload ["password" ],
147147 reset = True ,
148148 )
149- self .fields_map = component_config [ "map" ] if "map" in component_config else None
149+ self .fields_map = component_config . get ( "map" )
150150 self .tables = [
151151 getattr (
152152 dj .VirtualModule (
@@ -158,115 +158,109 @@ def __init__(
158158 )
159159 for s , t in (_ .split ("." ) for _ in component_config ["tables" ])
160160 ]
161-
162- def _get_datatype_map (self ):
163- attributes = reduce (
164- lambda a0 , a1 : {** a0 , ** a1 }, (t .heading .attributes for t in self .tables )
161+ self .parents = set (
162+ [
163+ p
164+ for t in self .tables
165+ for p in t .parents (as_objects = True )
166+ if p .full_table_name not in (t .full_table_name for t in self .tables )
167+ ]
165168 )
166- datatype_map = {k : v .type for k , v in attributes .items ()}
167- return datatype_map
168169
169170 def dj_query_route (self ):
170171 with self .connection .transaction :
171- if self .fields_map :
172- field_name_map = {}
173- for field in self .fields_map :
174- if field ["type" ] != "table" :
175- field_name_map [
176- field ["input" ] if "input" in field else field ["destination" ]
177- ] = field ["destination" ]
178- else :
179- for submap in field ["map" ]:
180- field_name_map [
181- submap ["input" ]
182- if "input" in submap
183- else submap ["destination" ]
184- ] = submap ["destination" ]
185- self .payload = {field_name_map [k ]: v for k , v in self .payload .items ()}
172+ destination_lookup = reduce (
173+ lambda m0 , m1 : dict (
174+ m0 ,
175+ ** (
176+ {
177+ m_t ["input" ]
178+ if "input" in m_t
179+ else m_t ["destination" ]: m_t ["destination" ]
180+ for m_t in m1 ["map" ]
181+ }
182+ if m1 ["type" ] == "table"
183+ else {
184+ m1 ["input" ]
185+ if "input" in m1
186+ else m1 ["destination" ]: m1 ["destination" ]
187+ }
188+ ),
189+ ),
190+ self .fields_map or [],
191+ {},
192+ )
186193 for t in self .tables :
187- t .insert1 (
188- {k : v for k , v in self .payload .items () if k in t .heading .attributes }
194+ t .insert (
195+ [
196+ {
197+ a : v
198+ for k , v in r .items ()
199+ if (a := destination_lookup .get (k , k ))
200+ in t .heading .attributes
201+ }
202+ for r in self .payload ["submissions" ]
203+ ]
189204 )
190205 return "Insert successful"
191206
192207 def fields_route (self ):
193- fields = []
194- if self .fields_map :
195- datatype_map = self ._get_datatype_map ()
196- for field in self .fields_map :
197- field_type = field ["type" ]
198- field_name = (
199- field ["input" ] if "input" in field else field ["destination" ]
200- )
201- if field_type == "attribute" :
202- field_datatype = datatype_map [field ["destination" ]]
203- fields .append (
204- dict (type = field_type , datatype = field_datatype , name = field_name )
205- )
206- elif field_type == "table" :
207- s , t = field ["destination" ].split ("." )
208- if "map" in field :
209- proj_map = {
210- attr ["input" ]
211- if "input" in attr
212- else attr ["destination" ]: attr ["destination" ]
213- for attr in field ["map" ]
214- }
215- records = (
216- getattr (
217- dj .VirtualModule (
218- s ,
219- s ,
220- connection = self .connection ,
221- ),
222- t ,
223- )
224- .proj (** proj_map )
225- .fetch ("KEY" )
226- )
227- else :
228- records = getattr (
229- dj .VirtualModule (
230- s ,
231- s ,
232- connection = self .connection ,
233- ),
234- t ,
235- ).fetch ("KEY" )
236- fields .append (
237- dict (type = field_type , values = records , name = field_name )
238- )
239- else :
240- for t in self .tables :
241- for v in t .heading .attributes .values ():
242- is_fk = False
243- for p in t .parents (as_objects = True ):
244- if v .name in p .primary_key :
245- is_fk = True
246- field_name = (
247- f"{ p .database } .{ dj .utils .to_camel_case (p .table_name )} "
248- )
249- if field_name not in [
250- field ["name" ] for field in fields
251- ] and field_name not in [
252- f"{ t .database } .{ t .__name__ } " for t in self .tables
253- ]:
254- fields .append (
255- dict (
256- type = "table" ,
257- values = p .fetch ("KEY" ),
258- name = field_name ,
208+ parent_attributes = set (sum ([p .primary_key for p in self .parents ], []))
209+ source_fields = {
210+ ** {
211+ (p_name := f"{ p .database } .{ dj .utils .to_camel_case (p .table_name )} " ): {
212+ "values" : p .fetch ("KEY" , as_dict = True ),
213+ "type" : "table" ,
214+ "name" : p_name ,
215+ }
216+ for p in self .parents
217+ },
218+ ** {
219+ a : {"datatype" : v .type , "type" : "attribute" , "name" : v .name }
220+ for t in self .tables
221+ for a , v in t .heading .attributes .items ()
222+ if a not in parent_attributes
223+ },
224+ }
225+
226+ if not self .fields_map :
227+ return dict (fields = source_fields )
228+ return dict (
229+ fields = [
230+ dict (
231+ (field := source_fields .pop (m ["destination" ])),
232+ name = m ["input" if "input" in m else "destination" ],
233+ ** (
234+ {
235+ "values" : field ["values" ]
236+ if "map" not in m
237+ else [
238+ {
239+ input_lookup [k ]: v
240+ for k , v in r .items ()
241+ if k
242+ in (
243+ input_lookup := {
244+ table_m ["destination" ]: table_m [
245+ "input"
246+ if "input" in table_m
247+ else "destination"
248+ ]
249+ for table_m in m ["map" ]
250+ }
259251 )
260- )
261- if not is_fk :
262- fields .append (
263- dict (
264- type = "attribute" ,
265- datatype = v .type ,
266- name = v .name ,
267- )
268- )
269- return dict (fields = fields )
252+ }
253+ for r in field ["values" ]
254+ ]
255+ }
256+ if m ["type" ] == "table"
257+ else {}
258+ ),
259+ )
260+ for m in self .fields_map
261+ ]
262+ + list (source_fields .values ())
263+ )
270264
271265
272266class TableComponent (FetchComponent ):
0 commit comments