Thursday, September 17, 2020

PyQGIS - Get attribute column names and dataType

 Ocationally, I did like to check the attribute fields/columns of a layer I am working on. Sometimes to get their names, types or just to get the count of how many fields/columns are on that layer.

You could access some of these information when you open the layer's property window, under the information tab as seen below.


In this article, I did like to access these information in a way that I can send it to my client who knows nothing about QGIS. So, basically the client has many shapefiles with many attribute fields and he want me to extract all the field/column names and their data types.

One way to automate this is to use the PyQGIS API. The algorithm will look like this:-

  • Read the shapefile
  • Read the attribute fields
  • Read the each field's data type
  • Write the outputs above to text file


# Read active layer from the QGIS layer panel or read the shapefile from its path
layer = qgis.utils.iface.activeLayer()

# vector_file = r"C:\path_to_shapefile.shp"
# layer = QgsVectorLayer(vector_file, 'DISPLAYNAME', 'ogr')

# Count the number of feature (rows) and number of fields (columns)
faetureCount = layer.featureCount()
fieldCount = layer.fields().count()

# Loop through the layer fields to get each field name and type
data_list = []
for field in layer.fields():
    field_name = field.name()
    field_type = field.typeName()

    data = field_name, field_type
    data_list.append(data)


# Write the data_list to text file...
txtFileName = layer.name() # from layer name
with open(txtFileName +'.txt', 'w', encoding="utf-8") as f:
    print(data_list, end='\n', file = f)


As seen in the script, it basically make use of two methods from the QgsField Class namely: name() and typeName() that returns the name of the field and gets the field type respectively.


The Output:-

To see the output text file, open the current/default working directory (or simply whereever your script is running from). Use OS module to get the path like so...
import os
print(os.getcwd())

[('Electoral_', 'Integer64'), ('Electoral1', 'String'), ('Electora_1', 'String'), ('Electora_2', 'String'), ('Electora_3', 'String'), ('Electora_4', 'String'), ('Electora_5', 'String'), ('Electora_6', 'String'), ('Electora_7', 'String'), ('Electora_8', 'String'), ('Electora_9', 'String'), ('Elector_10', 'String'), ('Elector_11', 'String'), ('Elector_12', 'Real'), ('Elector_13', 'Real'), ('c2016Depri', 'Integer64'), ('c2016Dep_1', 'String'), ('c2016Dep_2', 'String'), ('c2016Dep_3', 'String'), ('c2016Dep_4', 'String'), ('c2016Dep_5', 'String'), ('c2016Dep_6', 'String'), ('c2016Dep_7', 'String'), ('c2016Dep_8', 'String'), ('c2016Dep_9', 'Real'), ('c2016De_10', 'Real'), ('c2016De_11', 'Real'), ('c2016De_12', 'Real'), ('c2016De_13', 'Real'), ('c2016De_14', 'Real'), ('c2016De_15', 'Real'), ('c2016De_16', 'Integer64'), ('c2016De_17', 'Integer64'), ('c2016De_18', 'Integer64'), ('c2016De_19', 'Integer64'), ('c2016De_20', 'Real'), ('c2016De_21', 'Real'), ('c2016De_22', 'Real'), ('c2016De_23', 'Real'), ('c2016De_24', 'Real'), ('c2016De_25', 'Real'), ('c2016De_26', 'Real'), ('c2016De_27', 'Real'), ('c2016De_28', 'Real'), ('c2016De_29', 'Real'), ('c2016De_30', 'Real'), ('c2016De_31', 'Real'), ('c2016De_32', 'Real'), ('c2016De_33', 'Real'), ('c2016De_34', 'Real'), ('c2016De_35', 'Real'), ('c2016De_36', 'Real'), ('c2016De_37', 'Real'), ('c2016De_38', 'Real'), ('c2016De_39', 'Real'), ('c2016De_40', 'Real'), ('c2016De_41', 'Real'), ('c2016De_42', 'Real'), ('c2016De_43', 'Real'), ('c2016De_44', 'Real'), ('c2016De_45', 'Real'), ('c2016De_46', 'Real'), ('c2016De_47', 'Real'), ('c2016De_48', 'Real'), ('c2016De_49', 'Real'), ('c2016De_50', 'Real'), ('c2016De_51', 'Real'), ('c2016De_52', 'Real'), ('c2016De_53', 'Real'), ('c2016De_54', 'Real'), ('c2016De_55', 'Real'), ('c2016De_56', 'Real'), ('c2016De_57', 'Real'), ('c2016De_58', 'Real'), ('c2016De_59', 'Real'), ('c2016De_60', 'Real'), ('c2016De_61', 'Real'), ('c2016De_62', 'Real'), ('c2016De_63', 'Real'), ('c2016De_64', 'Real'), ('c2016De_65', 'Real'), ('c2016De_66', 'Real'), ('Shape_Leng', 'Real'), ('Shape_Area', 'Real')]



Note that the final output could be formated into desired format before writting it to file. Here we just needed it as a list format in the text file.

If you like to save it to a spreadsheet, here below is how to do it using pandas module.

import pandas as pd
df = pd.DataFrame(data_list)
df.to_excel(txtFileName +'.xlsx', index=None)
print(df)

Thant is it!

No comments:

Post a Comment