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
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)
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
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))
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)
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
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
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
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