Exemplo n.º 1
0
 def uri(self):
     uri = super().uri()
     for f in self.fields():
         if f.primaryKey:
             uri.setKeyColumn(f.name)
             break
     uri.setWkbType(QgsWkbTypes.parseType(self.geomType))
     return uri
Exemplo n.º 2
0
    def toMapLayer(self, geometryType=None, crs=None):
        provider = self.database().dbplugin().providerName()
        dataSourceUri = self.uri()
        if geometryType:
            dataSourceUri.setWkbType(QgsWkbTypes.parseType(geometryType))

        if crs:
            dataSourceUri.setSrid(str(crs.postgisSrid()))

        uri = dataSourceUri.uri(False)
        if self.type == Table.RasterType:
            return QgsRasterLayer(uri, self.name, provider)
        return QgsVectorLayer(uri, self.name, provider)
Exemplo n.º 3
0
    def uri(self):
        uri = self.database().uri()
        schema = self.schemaName() if self.schemaName() else ''
        geomCol = self.geomColumn if self.type in [
            Table.VectorType, Table.RasterType
        ] else ""
        uniqueCol = self.getValidQgisUniqueFields(
            True) if self.isView else None
        uri.setDataSource(schema, self.name, geomCol if geomCol else None,
                          None, uniqueCol.name if uniqueCol else "")
        uri.setSrid(str(self.srid))
        for f in self.fields():
            if f.primaryKey:
                uri.setKeyColumn(f.name)
                break
        uri.setWkbType(QgsWkbTypes.parseType(self.geomType))

        return uri
Exemplo n.º 4
0
    def get_uri_for_layer(self, layer_name, geometry_type=None):
        res, cur = self.get_tables_info()
        if not res:
            return (res, cur)
        data_source_uri = ''

        for record in cur:
            if record['schemaname'] == self.schema and record['tablename'] == layer_name.lower():
                if record['geometry_column']:
                    if geometry_type is not None:
                        if QgsWkbTypes.geometryType(QgsWkbTypes.parseType(record['type'])) == geometry_type:
                            data_source_uri = '{uri} key={primary_key} estimatedmetadata=true srid={srid} type={type} table="{schema}"."{table}" ({geometry_column})'.format(
                                uri=self._uri,
                                primary_key=record['primary_key'],
                                srid=record['srid'],
                                type=record['type'],
                                schema=record['schemaname'],
                                table=record['tablename'],
                                geometry_column=record['geometry_column']
                            )
                    else:
                        data_source_uri = '{uri} key={primary_key} estimatedmetadata=true srid={srid} type={type} table="{schema}"."{table}" ({geometry_column})'.format(
                            uri=self._uri,
                            primary_key=record['primary_key'],
                            srid=record['srid'],
                            type=record['type'],
                            schema=record['schemaname'],
                            table=record['tablename'],
                            geometry_column=record['geometry_column']
                        )
                else:
                    data_source_uri = '{uri} key={primary_key} table="{schema}"."{table}"'.format(
                        uri=self._uri,
                        primary_key=record['primary_key'],
                        schema=record['schemaname'],
                        table=record['tablename']
                    )
        if data_source_uri:
            return (True, data_source_uri)
        return (False, QCoreApplication.translate("PGConnector", "Layer '{}' was not found in the database (schema: {}).").format(layer_name, self.schema))
Exemplo n.º 5
0
 def add_geom_layers(self, db, query, params):
     view_name = params['view_name']
     col_names = params['col_names']
     srids = params['srids']
     geom_types = params['geom_types']
     for i in range(len(col_names)):
         col_types = geom_types[i]
         for col_type in col_types:
             uri = QgsDataSourceUri()
             uri.setConnection(db['host'], db['port'], db['database'],
                               db['username'], db['password'],
                               QgsDataSourceUri.SslDisable)
             uri.setDataSource("public", view_name, col_names[i], "", "id")
             uri.setSrid(str(srids[i]))
             uri.setWkbType(QgsWkbTypes.parseType(col_type))
             layer_name = col_names[i]
             layer = self.iface.addVectorLayer(uri.uri(), layer_name,
                                               "postgres")
             if not layer or not layer.isValid():
                 self.msg("Layer failed to load!")
             else:
                 layer.setCustomProperty('move/view_name', view_name)
                 layer.setCustomProperty('move/sql', query.raw_sql)
Exemplo n.º 6
0
    def layers(self, filter_layer_list=[]):
        tables_info = self.get_tables_info()
        layers = list()

        for record in tables_info:
            # When in PostGIS mode, leaving schema blank should load tables from
            # all schemas, except the ignored ones
            if self.schema:
                if record['schemaname'] != self.schema:
                    continue
            elif record['schemaname'] in IGNORED_SCHEMAS:
                continue

            if record['tablename'] in IGNORED_TABLES:
                continue

            if filter_layer_list and record[
                    'tablename'] not in filter_layer_list:
                continue

            if self.tool_name == 'ili2pg':
                provider = 'postgres'
                if record['geometry_column']:
                    data_source_uri = '{uri} key={primary_key} estimatedmetadata=true srid={srid} type={type} table="{schema}"."{table}" ({geometry_column})'.format(
                        uri=self.uri,
                        primary_key=record['primary_key'],
                        srid=record['srid'],
                        type=record['type'],
                        schema=record['schemaname'],
                        table=record['tablename'],
                        geometry_column=record['geometry_column'])
                else:
                    data_source_uri = '{uri} key={primary_key} table="{schema}"."{table}"'.format(
                        uri=self.uri,
                        primary_key=record['primary_key'],
                        schema=record['schemaname'],
                        table=record['tablename'])
            elif self.tool_name == 'ili2gpkg':
                provider = 'ogr'
                data_source_uri = '{uri}|layername={table}'.format(
                    uri=self.uri, table=record['tablename'])

            alias = record['table_alias'] if 'table_alias' in record else ''
            is_domain = record['kind_settings'] == 'ENUM' or record[
                'kind_settings'] == 'CATALOGUE' if 'kind_settings' in record else False
            is_nmrel = record[
                'kind_settings'] == 'ASSOCIATION' if 'kind_settings' in record else False
            layer = Layer(
                provider, data_source_uri, record['tablename'],
                record['geometry_column'],
                QgsWkbTypes.parseType(record['type']) or QgsWkbTypes.Unknown,
                alias, is_domain, is_nmrel)

            # Configure fields for current table
            fields_info = self.get_fields_info(record['tablename'])
            constraints_info = self.get_constraints_info(record['tablename'])
            re_iliname = re.compile(r'^@iliname (.*)$')

            for fielddef in fields_info:
                column_name = fielddef['column_name']
                comment = fielddef['comment']
                m = re_iliname.match(comment) if comment else None

                alias = None
                if 'column_alias' in fielddef:
                    alias = fielddef['column_alias']
                if m and not alias:
                    alias = m.group(1)

                field = Field(column_name)
                field.alias = alias

                if column_name in IGNORED_FIELDNAMES:
                    field.widget = 'Hidden'

                if column_name in READONLY_FIELDNAMES:
                    field.read_only = True

                if column_name in constraints_info:
                    field.widget = 'Range'
                    field.widget_config['Min'] = constraints_info[column_name][
                        0]
                    field.widget_config['Max'] = constraints_info[column_name][
                        1]
                    # field.widget_config['Suffix'] = fielddef['unit'] if 'unit' in fielddef else ''
                    if 'unit' in fielddef:
                        field.alias = '{alias} [{unit}]'.format(
                            alias=alias or column_name, unit=fielddef['unit'])

                if 'texttype' in fielddef and fielddef['texttype'] == 'MTEXT':
                    field.widget = 'TextEdit'
                    field.widget_config['IsMultiline'] = True

                data_type = self._db_connector.map_data_types(
                    fielddef['data_type'])
                if 'time' in data_type or 'date' in data_type:
                    field.widget = 'DateTime'
                    field.widget_config['calendar_popup'] = True

                    dateFormat = QLocale(
                        QgsApplication.instance().locale()).dateFormat(
                            QLocale.ShortFormat)
                    timeFormat = QLocale(
                        QgsApplication.instance().locale()).timeFormat(
                            QLocale.ShortFormat)
                    dateTimeFormat = QLocale(
                        QgsApplication.instance().locale()).dateTimeFormat(
                            QLocale.ShortFormat)

                    if data_type == self._db_connector.QGIS_TIME_TYPE:
                        field.widget_config['display_format'] = timeFormat
                    elif data_type == self._db_connector.QGIS_DATE_TIME_TYPE:
                        field.widget_config['display_format'] = dateTimeFormat
                    elif data_type == self._db_connector.QGIS_DATE_TYPE:
                        field.widget_config['display_format'] = dateFormat

                layer.fields.append(field)

            layers.append(layer)

        return layers
Exemplo n.º 7
0
    def layers(self, filter_layer_list=[]):
        tables_info = self.get_tables_info_without_ignored_tables()
        basket_handling = self.get_basket_handling()
        layers = list()

        db_factory = self.db_simple_factory.create_factory(self.tool)

        layer_uri = db_factory.get_layer_uri(self.uri)
        layer_uri.pg_estimated_metadata = self.pg_estimated_metadata

        # When a table has multiple geometry columns, it will be loaded multiple times (supported e.g. by PostGIS).
        table_appearance_count = {}

        for record in tables_info:
            if self.schema:
                if record["schemaname"] != self.schema:
                    continue
            if filter_layer_list and record[
                    "tablename"] not in filter_layer_list:
                continue
            table_appearance_count[record["tablename"]] = (
                table_appearance_count.get(record["tablename"], 0) + 1)

        for record in tables_info:
            # When in PostGIS mode, leaving schema blank should load tables from
            # all schemas, except the ignored ones
            if self.schema:
                if record["schemaname"] != self.schema:
                    continue

            if filter_layer_list and record[
                    "tablename"] not in filter_layer_list:
                continue

            is_domain = (record.get("kind_settings") == "ENUM"
                         or record.get("kind_settings") == "CATALOGUE")
            is_attribute = bool(record.get("attribute_name"))
            is_structure = record.get("kind_settings") == "STRUCTURE"
            is_nmrel = record.get("kind_settings") == "ASSOCIATION"
            is_basket_table = (record.get("tablename") ==
                               self._db_connector.basket_table_name)
            is_dataset_table = (record.get("tablename") ==
                                self._db_connector.dataset_table_name)

            alias = record["table_alias"] if "table_alias" in record else None
            if not alias:
                short_name = None
                if is_domain and is_attribute:
                    short_name = ""
                    if "ili_name" in record and record["ili_name"]:
                        short_name = (record["ili_name"].split(".")[-2] + "_" +
                                      record["ili_name"].split(".")[-1])
                else:
                    if (table_appearance_count[record["tablename"]] > 1
                            and "geometry_column" in record):
                        # multiple layers for this table - append geometry column to name
                        fields_info = self.get_fields_info(record["tablename"])
                        for field_info in fields_info:
                            if field_info["column_name"] == record[
                                    "geometry_column"]:
                                if ("fully_qualified_name" in field_info and
                                        field_info["fully_qualified_name"]):
                                    short_name = (
                                        field_info["fully_qualified_name"].
                                        split(".")[-2] + " (" +
                                        field_info["fully_qualified_name"].
                                        split(".")[-1] + ")")
                                else:
                                    short_name = record["tablename"]
                    elif "ili_name" in record and record["ili_name"]:
                        match = re.search(r"([^\(]*).*", record["ili_name"])
                        if match.group(0) == match.group(1):
                            short_name = match.group(1).split(".")[-1]
                        else:
                            # additional brackets in the the name - extended layer in geopackage
                            short_name = (match.group(1).split(".")[-2] +
                                          " (" +
                                          match.group(1).split(".")[-1] + ")")
                alias = short_name

            model_topic_name = ""
            if "ili_name" in record and record["ili_name"]:
                if record["ili_name"].count(".") > 1:
                    model_topic_name = f"{record['ili_name'].split('.')[0]}.{record['ili_name'].split('.')[1]}"

            display_expression = ""
            if is_basket_table:
                display_expression = "coalesce(attribute(get_feature('{dataset_layer_name}', '{tid}', dataset), 'datasetname') || ' (' || topic || ') ', coalesce( attribute(get_feature('{dataset_layer_name}', '{tid}', dataset), 'datasetname'), {tilitid}))".format(
                    tid=self._db_connector.tid,
                    tilitid=self._db_connector.tilitid,
                    dataset_layer_name=self._db_connector.dataset_table_name,
                )
            elif "ili_name" in record and record["ili_name"]:
                meta_attrs = self.get_meta_attrs(record["ili_name"])
                for attr_record in meta_attrs:
                    if attr_record["attr_name"] == "dispExpression":
                        display_expression = attr_record["attr_value"]

            coord_decimals = (record["coord_decimals"]
                              if "coord_decimals" in record else None)
            coordinate_precision = None
            if coord_decimals:
                coordinate_precision = 1 / (10**coord_decimals)

            layer = Layer(
                layer_uri.provider,
                layer_uri.get_data_source_uri(record),
                record["tablename"],
                record["srid"],
                record["extent"] if "extent" in record else None,
                record["geometry_column"],
                QgsWkbTypes.parseType(record["type"]) or QgsWkbTypes.Unknown,
                alias,
                is_domain,
                is_structure,
                is_nmrel,
                display_expression,
                coordinate_precision,
                is_basket_table,
                is_dataset_table,
                model_topic_name,
            )

            # Configure fields for current table
            fields_info = self.get_fields_info(record["tablename"])
            min_max_info = self.get_min_max_info(record["tablename"])
            value_map_info = self.get_value_map_info(record["tablename"])
            re_iliname = re.compile(r".*\.(.*)$")

            for fielddef in fields_info:
                column_name = fielddef["column_name"]
                fully_qualified_name = (fielddef["fully_qualified_name"]
                                        if "fully_qualified_name" in fielddef
                                        else None)
                m = (re_iliname.match(fully_qualified_name)
                     if fully_qualified_name else None)

                alias = None
                if "column_alias" in fielddef:
                    alias = fielddef["column_alias"]
                if m and not alias:
                    alias = m.group(1)

                field = Field(column_name)
                field.alias = alias

                # Should we hide the field?
                hide_attribute = False

                if "fully_qualified_name" in fielddef:
                    fully_qualified_name = fielddef["fully_qualified_name"]
                    if fully_qualified_name:
                        meta_attrs_column = self.get_meta_attrs(
                            fully_qualified_name)

                        for attr_record in meta_attrs_column:
                            if attr_record["attr_name"] == "hidden":
                                if attr_record["attr_value"] == "True":
                                    hide_attribute = True
                                    break

                if column_name in IGNORED_FIELDNAMES:
                    hide_attribute = True

                if not basket_handling and column_name in BASKET_FIELDNAMES:
                    hide_attribute = True

                field.hidden = hide_attribute

                if column_name in READONLY_FIELDNAMES:
                    field.read_only = True

                if column_name in min_max_info:
                    field.widget = "Range"
                    field.widget_config["Min"] = min_max_info[column_name][0]
                    field.widget_config["Max"] = min_max_info[column_name][1]
                    if "numeric_scale" in fielddef:
                        field.widget_config["Step"] = pow(
                            10, -1 * fielddef["numeric_scale"])
                    # field.widget_config['Suffix'] = fielddef['unit'] if 'unit' in fielddef else ''
                    if "unit" in fielddef and fielddef["unit"] is not None:
                        field.alias = "{alias} [{unit}]".format(
                            alias=alias or column_name, unit=fielddef["unit"])

                if column_name in value_map_info:
                    field.widget = "ValueMap"
                    field.widget_config["map"] = [{
                        val: val
                    } for val in value_map_info[column_name]]

                if "attr_mapping" in fielddef and fielddef[
                        "attr_mapping"] == "ARRAY":
                    field.widget = "List"

                if "texttype" in fielddef and fielddef["texttype"] == "MTEXT":
                    field.widget = "TextEdit"
                    field.widget_config["IsMultiline"] = True

                data_type = self._db_connector.map_data_types(
                    fielddef["data_type"])
                if "time" in data_type or "date" in data_type:
                    field.widget = "DateTime"
                    field.widget_config["calendar_popup"] = True

                    dateFormat = QLocale(
                        QgsApplication.instance().locale()).dateFormat(
                            QLocale.ShortFormat)
                    timeFormat = QLocale(
                        QgsApplication.instance().locale()).timeFormat(
                            QLocale.ShortFormat)
                    dateTimeFormat = QLocale(
                        QgsApplication.instance().locale()).dateTimeFormat(
                            QLocale.ShortFormat)

                    if data_type == self._db_connector.QGIS_TIME_TYPE:
                        field.widget_config["display_format"] = timeFormat
                    elif data_type == self._db_connector.QGIS_DATE_TIME_TYPE:
                        field.widget_config["display_format"] = dateTimeFormat
                    elif data_type == self._db_connector.QGIS_DATE_TYPE:
                        field.widget_config["display_format"] = dateFormat

                db_factory.customize_widget_editor(field, data_type)

                if "default_value_expression" in fielddef:
                    field.default_value_expression = fielddef[
                        "default_value_expression"]

                if basket_handling and column_name in BASKET_FIELDNAMES:
                    if self.tool in [
                            DbIliMode.pg,
                            DbIliMode.ili2pg,
                            DbIliMode.mssql,
                            DbIliMode.ili2mssql,
                    ]:
                        schema_topic_identificator = slugify(
                            f"{layer.source().host()}_{layer.source().database()}_{layer.source().schema()}_{model_topic_name}"
                        )
                        field.default_value_expression = (
                            f"@{schema_topic_identificator}")
                    elif self.tool in [DbIliMode.ili2gpkg, DbIliMode.gpkg]:
                        schema_topic_identificator = slugify(
                            f"@{layer.source().uri().split('|')[0].strip()}_{model_topic_name}"
                        )
                        field.default_value_expression = (
                            f"@{schema_topic_identificator}")

                if "enum_domain" in fielddef and fielddef["enum_domain"]:
                    field.enum_domain = fielddef["enum_domain"]

                layer.fields.append(field)

            layers.append(layer)

        self.print_messages()

        return layers
Exemplo n.º 8
0
 def _group_geom_name(self, geom_str):
     geom = QgsWkbTypes.geometryDisplayString(
         QgsWkbTypes.geometryType(
         QgsWkbTypes.parseType(
         geom_str))) if geom_str else self.NO_GEOM
     return geom 
Exemplo n.º 9
0
    def layers(self, filter_layer_list=[]):
        tables_info = self.get_tables_info()
        layers = list()

        db_factory = self.db_simple_factory.create_factory(self.tool)

        layer_uri = db_factory.get_layer_uri(self.uri)
        layer_uri.pg_estimated_metadata = self.pg_estimated_metadata

        for record in tables_info:
            # When in PostGIS mode, leaving schema blank should load tables from
            # all schemas, except the ignored ones
            if self.schema:
                if record['schemaname'] != self.schema:
                    continue
            elif record['schemaname'] in IGNORED_SCHEMAS:
                continue

            if record['tablename'] in IGNORED_TABLES:
                continue

            if filter_layer_list and record['tablename'] not in filter_layer_list:
                continue

            alias = record['table_alias'] if 'table_alias' in record else ''
            is_domain = record['kind_settings'] == 'ENUM' or record[
                'kind_settings'] == 'CATALOGUE' if 'kind_settings' in record else False
            is_structure = record['kind_settings'] == 'STRUCTURE' if 'kind_settings' in record else False
            is_nmrel = record['kind_settings'] == 'ASSOCIATION' if 'kind_settings' in record else False

            display_expression = ''
            if 'ili_name' in record:
                meta_attrs = self.get_meta_attrs(record['ili_name'])
                for attr_record in meta_attrs:
                    if attr_record['attr_name'] == 'dispExpression':
                        display_expression = attr_record['attr_value']

            layer = Layer(layer_uri.provider,
                          layer_uri.get_data_source_uri(record),
                          record['tablename'],
                          record['srid'],
                          record['extent'] if 'extent' in record else None,
                          record['geometry_column'],
                          QgsWkbTypes.parseType(
                              record['type']) or QgsWkbTypes.Unknown,
                          alias,
                          is_domain,
                          is_structure,
                          is_nmrel,
                          display_expression)

            # Configure fields for current table
            fields_info = self.get_fields_info(record['tablename'])
            constraints_info = self.get_constraints_info(record['tablename'])
            re_iliname = re.compile(r'^@iliname (.*)$')

            for fielddef in fields_info:
                column_name = fielddef['column_name']
                comment = fielddef['comment']
                m = re_iliname.match(comment) if comment else None

                alias = None
                if 'column_alias' in fielddef:
                    alias = fielddef['column_alias']
                if m and not alias:
                    alias = m.group(1)

                field = Field(column_name)
                field.alias = alias

                # Should we hide the field?
                hide_attribute = False

                if 'fully_qualified_name' in fielddef:
                    fully_qualified_name = fielddef['fully_qualified_name']
                    if fully_qualified_name:
                        meta_attrs_column = self.get_meta_attrs(fully_qualified_name)

                        for attr_record in meta_attrs_column:
                            if attr_record['attr_name'] == 'hidden':
                                if attr_record['attr_value'] == 'True':
                                    hide_attribute = True
                                    break

                if column_name in IGNORED_FIELDNAMES:
                    hide_attribute = True

                field.hidden = hide_attribute

                if column_name in READONLY_FIELDNAMES:
                    field.read_only = True

                if column_name in constraints_info:
                    field.widget = 'Range'
                    field.widget_config['Min'] = constraints_info[column_name][0]
                    field.widget_config['Max'] = constraints_info[column_name][1]
                    if 'numeric_scale' in fielddef:
                        field.widget_config['Step'] = pow(10, -1 * fielddef['numeric_scale'])
                    # field.widget_config['Suffix'] = fielddef['unit'] if 'unit' in fielddef else ''
                    if 'unit' in fielddef and fielddef['unit'] is not None:
                        field.alias = '{alias} [{unit}]'.format(
                            alias=alias or column_name, unit=fielddef['unit'])

                if 'texttype' in fielddef and fielddef['texttype'] == 'MTEXT':
                    field.widget = 'TextEdit'
                    field.widget_config['IsMultiline'] = True

                data_type = self._db_connector.map_data_types(
                    fielddef['data_type'])
                if 'time' in data_type or 'date' in data_type:
                    field.widget = 'DateTime'
                    field.widget_config['calendar_popup'] = True

                    dateFormat = QLocale(QgsApplication.instance(
                    ).locale()).dateFormat(QLocale.ShortFormat)
                    timeFormat = QLocale(QgsApplication.instance(
                    ).locale()).timeFormat(QLocale.ShortFormat)
                    dateTimeFormat = QLocale(QgsApplication.instance(
                    ).locale()).dateTimeFormat(QLocale.ShortFormat)

                    if data_type == self._db_connector.QGIS_TIME_TYPE:
                        field.widget_config['display_format'] = timeFormat
                    elif data_type == self._db_connector.QGIS_DATE_TIME_TYPE:
                        field.widget_config['display_format'] = dateTimeFormat
                    elif data_type == self._db_connector.QGIS_DATE_TYPE:
                        field.widget_config['display_format'] = dateFormat

                db_factory.customize_widget_editor(field, data_type)

                if 'default_value_expression' in fielddef:
                    field.default_value_expression = fielddef['default_value_expression']

                layer.fields.append(field)

            layers.append(layer)

        return layers