Script for validating the entries made by the user in pyqgis

Viewed 24

I am writing a script in pyqgis which should perform the following task:

  1. First it should read a csv file which we consider it as a input csv,csv file will be something like this:

    layer  ,columnname     ,condition        ,values              
    layer1 ,id             ,not blank        ,                    
    layer1 ,type           ,matching         ,type1,type2,type3,NA
    layer2 ,gisid          ,not blank,integer,                    
    layer2 ,layer_condition,matching         ,a,b,c,d             
    
  2. It should read layer name unique and check whether those layer is present or not

  3. layer will be having the columns mentioned in the csv it should check based on the condition column for example in layer1 for column id condition is not blank so all the features in the layer should not have any null values or blank spaces and for column like type condition is matching so all the feautre values should have one of the values mentioned in the values column.

So far i have tried the following code:

import csv

layer=QgsProject.instance().mapLayersByName('layer1')[0]

with open(r'layer1_Validation.csv') as file_obj:

    reader_obj = csv.DictReader(file_obj)

    for i,row in enumerate(reader_obj):
        
        if row['Condition'] == "Matching":

            a=row['values'].split(',')

            column=row['ColumnName']

            print(a)

            print(column)

            for f in layer.getFeatures():

                for s in a:

                    if f[column] == a:

                        print(f.id())

            break
1 Answers

For the above question i tried my self and came up with the following code:

import csv
import pandas as pd
csv_path = r"E:\sample.csv"
df=pd.read_csv(csv_path)
df1=df.loc[df['Condition'].eq('Matching')]['ColumnName'].values


for i in df['LayerName'].unique():
    layer=QgsProject.instance().mapLayersByName(i)[0]
    for field in layer.fields():
        current_field=field.name()
            if (current_field in  df1):
                with open(csv_path) as file_obj:
                    reader_obj = csv.DictReader(file_obj)
                    for row in reader_obj:
                        if row['Condition'] == "Matching" and row['ColumnName'] == current_field:
                            a=(word.strip() for word in row['values'].split(','))
                            query = "Select PID" + " from " + layer.name()+" where "+current_field+" not in "+str(tuple(a))+" or "+current_field+" is NULL group by PID"
                            vlayer = QgsVectorLayer( "?query={}".format(query), layer.name()+"_"+current_field+"_errors", "virtual" )
                             QgsProject.instance().addMapLayer(vlayer)
                             index = vlayer.featureCount()
                             vlayer.setName(vlayer.name()+"[{}]".format(str(index)))
                             if index == 0:
                                 QgsProject.instance().removeMapLayer(vlayer)

Above script will take the csv file as input and for the matching condition it checks and if their are any errors it creates the virtual layer

Related