def insertDataPoints(self):
        reportId = self.reportId
        if self.filingPreviouslyInDB:
            self.showStatus("deleting prior data points of this report")
            # remove prior facts
            self.lockTables(("data_point", "entity_identifier", "period", "aspect_value_selection",
                             "aspect_value_selection_set", "unit_measure", "unit",
                             "table_data_points"))
            self.execute("DELETE FROM {0} WHERE {0}.report_id = {1}"
                         .format( self.dbTableName("data_point"), reportId), 
                         close=False, fetch=False)
            self.execute("DELETE FROM {0} WHERE {0}.report_id = {1}" 
                         .format( self.dbTableName("entity_identifier"), reportId), 
                         close=False, fetch=False)
            self.execute("DELETE FROM {0} WHERE {0}.report_id = {1}"
                         .format( self.dbTableName("period"), reportId), 
                         close=False, fetch=False)
            self.execute("DELETE from {0} "
                         "USING {1} "
                         "WHERE {1}.report_id = {2} AND {0}.aspect_value_selection_id = {1}.aspect_value_selection_id" 
                         .format( self.dbTableName("aspect_value_selection"), 
                                  self.dbTableName("aspect_value_selection_set"), 
                                  reportId), 
                         close=False, fetch=False)
            self.execute("DELETE FROM {0} WHERE {0}.report_id = {1};"
                         .format( self.dbTableName("aspect_value_selection_set"), reportId), 
                         close=False, fetch=False)
            self.execute("DELETE from {0} "
                         "USING {1} "
                         "WHERE {1}.report_id = {2} AND {0}.unit_id = {1}.unit_id"
                         .format( self.dbTableName("unit_measure"), 
                                  self.dbTableName("unit"), 
                                  reportId), 
                         close=False, fetch=False)
            self.execute("DELETE from {0} WHERE {0}.report_id = {1}"
                         .format( self.dbTableName("unit"), reportId), 
                         close=False, fetch=False)
            self.execute("DELETE FROM {0} WHERE {0}.report_id = {1}"
                         .format( self.dbTableName("table_data_points"), reportId), 
                         close=False, fetch=False)
        self.showStatus("insert data points")
        # units
        table = self.getTable('unit', 'unit_id', 
                              ('report_id', 'xml_id', 'xml_child_seq', 'measures_hash'), 
                              ('report_id', 'measures_hash'), 
                              tuple((reportId,
                                     unit.id,
                                     elementChildSequence(unit),
                                     unit.md5hash)
                                    for unit in dict((unit.md5hash,unit) # deduplicate by md5hash
                                                     for unit in self.modelXbrl.units.values()).values()))
        self.unitId = dict(((_reportId, measuresHash), id)
                           for id, _reportId, measuresHash in table)
        # measures
        table = self.getTable('unit_measure', 
                              None, 
                              ('unit_id', 'qname', 'is_multiplicand'), 
                              ('unit_id', 'qname', 'is_multiplicand'), 
                              tuple((self.unitId[(reportId,unit.md5hash)],
                                     measure.clarkNotation,
                                     i == 0)
                                    for unit in self.modelXbrl.units.values()
                                    for i in range(2)
                                    for measure in unit.measures[i]))
        table = self.getTable('entity_identifier', 'entity_identifier_id', 
                              ('report_id', 'scheme', 'identifier'), 
                              ('report_id', 'scheme', 'identifier'), 
                              set((reportId,
                                   cntx.entityIdentifier[0],
                                   cntx.entityIdentifier[1])
                                for cntx in self.modelXbrl.contexts.values()),
                              checkIfExisting=True) # entities shared across multiple instance/inline docs
        self.entityIdentifierId = dict(((_reportId, entScheme, entIdent), id)
                                       for id, _reportId, entScheme, entIdent in table)
        table = self.getTable('period', 'period_id', 
                              ('report_id', 'start_date', 'end_date', 'is_instant', 'is_forever'), 
                              ('report_id', 'start_date', 'end_date', 'is_instant', 'is_forever'), 
                              set((reportId,
                                   cntx.startDatetime if cntx.isStartEndPeriod else None,
                                   cntx.endDatetime if (cntx.isStartEndPeriod or cntx.isInstantPeriod) else None,
                                   cntx.isInstantPeriod,
                                   cntx.isForeverPeriod)
                                for cntx in self.modelXbrl.contexts.values()),
                              checkIfExisting=True) # periods shared across multiple instance/inline docs
        self.periodId = dict(((_reportId, start, end, isInstant, isForever), id)
                             for id, _reportId, start, end, isInstant, isForever in table)
        
        def cntxDimsSet(cntx):
            return frozenset((self.aspectQnameId[modelDimValue.dimensionQname],
                              self.aspectQnameId.get(modelDimValue.memberQname),
                              modelDimValue.isTyped,
                              modelDimValue.stringValue if modelDimValue.isTyped else None)
                             for modelDimValue in cntx.qnameDims.values()
                             if modelDimValue.dimensionQname in self.aspectQnameId)
        
        cntxAspectValueSelectionSet = dict((cntx, cntxDimsSet(cntx))
                                            for cntx in self.modelXbrl.contexts.values())
        
        aspectValueSelections = set(aspectValueSelectionSet
                                    for cntx, aspectValueSelectionSet in cntxAspectValueSelectionSet.items()
                                    if aspectValueSelectionSet)
        self.lockTables(("aspect_value_selection_set",))
        self.execute("DELETE FROM {0} WHERE report_id = {1}"
                     .format(self.dbTableName("aspect_value_selection_set"), reportId), 
                     close=False, fetch=False)
        table = self.getTable('aspect_value_selection_set', 'aspect_value_selection_id', 
                              ('report_id', ), 
                              ('report_id', ), 
                              tuple((reportId,)
                                    for aspectValueSelection in aspectValueSelections)
                              )
        # assure we only get single entry per result (above gives cross product)
        table = self.execute("SELECT aspect_value_selection_id, report_id from {0} "
                             "WHERE report_id = {1}"
                             .format(self.dbTableName("aspect_value_selection_set"), reportId))
        aspectValueSelectionSets = dict((aspectValueSelections.pop(), id)
                                        for id, _reportId in table)
        
        cntxAspectValueSelectionSetId = dict((cntx, aspectValueSelectionSets[_cntxDimsSet])
                                             for cntx, _cntxDimsSet in cntxAspectValueSelectionSet.items()
                                             if _cntxDimsSet)
                                    
        table = self.getTable('aspect_value_selection', 
                              None, 
                              ('aspect_value_selection_id', 'aspect_id', 'aspect_value_id', 'is_typed_value', 'typed_value'), 
                              ('aspect_value_selection_id', ), 
                              tuple((aspectValueSetId, dimId, dimMbrId, isTyped, typedValue)
                                    for aspectValueSelection, aspectValueSetId in aspectValueSelectionSets.items()
                                    for dimId, dimMbrId, isTyped, typedValue in aspectValueSelection)
                              )

        # facts
        def insertFactSet(modelFacts, parentDatapointId):
            facts = []
            for fact in modelFacts:
                if fact.concept is not None and getattr(fact, "xValid", UNVALIDATED) >= VALID and fact.qname is not None:
                    cntx = fact.context
                    documentId = self.documentIds[fact.modelDocument]
                    facts.append((reportId,
                                  documentId,
                                  fact.id,
                                  elementChildSequence(fact),
                                  fact.sourceline,
                                  parentDatapointId, # parent ID
                                  self.aspectQnameId.get(fact.qname),
                                  fact.contextID,
                                  self.entityIdentifierId.get((reportId, cntx.entityIdentifier[0], cntx.entityIdentifier[1]))
                                      if cntx is not None else None,
                                      self.periodId.get((reportId,
                                                    cntx.startDatetime if cntx.isStartEndPeriod else None,
                                                    cntx.endDatetime if (cntx.isStartEndPeriod or cntx.isInstantPeriod) else None,
                                                    cntx.isInstantPeriod,
                                                    cntx.isForeverPeriod)) if cntx is not None else None,
                                  cntxAspectValueSelectionSetId.get(cntx) if cntx is not None else None,
                                  self.unitId.get((reportId,fact.unit.md5hash)) if fact.unit is not None else None,
                                  fact.isNil,
                                  fact.precision,
                                  fact.decimals,
                                  roundValue(fact.value, fact.precision, fact.decimals) if fact.isNumeric and not fact.isNil else None,
                                  fact.value
                                  ))
            table = self.getTable('data_point', 'datapoint_id', 
                                  ('report_id', 'document_id', 'xml_id', 'xml_child_seq', 'source_line', 
                                   'parent_datapoint_id',  # tuple
                                   'aspect_id',
                                   'context_xml_id', 'entity_identifier_id', 'period_id', 'aspect_value_selection_id', 'unit_id',
                                   'is_nil', 'precision_value', 'decimals_value', 'effective_value', 'value'), 
                                  ('document_id', 'xml_child_seq'), 
                                  facts)
            xmlIdDataPointId = dict(((docId, xml_child_seq), datapointId)
                                    for datapointId, docId, xml_child_seq in table)
            self.factDataPointId.update(xmlIdDataPointId)
            for fact in modelFacts:
                if fact.isTuple:
                    try:
                        insertFactSet(fact.modelTupleFacts, 
                                      xmlIdDataPointId[(self.documentIds[fact.modelDocument],
                                                        elementChildSequence(fact))])
                    except KeyError:
                        self.modelXbrl.info("xpDB:warning",
                                            _("Loading XBRL DB: tuple's datapoint not found: %(tuple)s"),
                                            modelObject=fact, tuple=fact.qname)

        self.factDataPointId = {}
        insertFactSet(self.modelXbrl.facts, None)
        # hashes
        if self.tableFacts: # if any entries
            tableDataPoints = []
            for roleType, tableCode, fact in self.tableFacts:
                try:
                    tableDataPoints.append((reportId,
                                            self.roleTypeIds[(self.documentIds[roleType.modelDocument], 
                                                              roleType.roleURI)],
                                            tableCode,
                                            self.factDataPointId[(self.documentIds[fact.modelDocument],
                                                                  elementChildSequence(fact))]))
                except __HOLE__:
                    # print ("missing table data points role or data point")
                    pass
            table = self.getTable('table_data_points', None, 
                                  ('report_id', 'object_id', 'table_code', 'datapoint_id'), 
                                  ('report_id', 'object_id', 'datapoint_id'), 
                                  tableDataPoints)
dataset/ETHPy150Open Arelle/Arelle/arelle/plugin/xbrlDB/XbrlSemanticSqlDB.py/XbrlSqlDatabaseConnection.insertDataPoints