My purpose: to be able to load a text to CSV directly with Python console in QGIS.

When I read the QGIS guide (https://docs.qgis.org/3.10/it/docs/pyqgis_developer_cookbook/loadlayer.html) for Python it seems that you can build an URI from a CSV file that you have in your folder.

With this Python expression in Python console in QGIS 3.10 you can load the CSV file into your project:

uri = "file://{}/testdata/delimited_xy.csv?delimiter={}&xField={}&yField={}".format(os.getcwd(), ";", "x", "y")
vlayer = QgsVectorLayer(uri, "layer name you like", "delimitedtext")

Critical aspect of the guide are the "{}", what does it mean? I tried to guess what to add inside "{}". So I tried to reconstruct the URI of the CSV file assuming that the first {} is referred for the path of the folder, the second should be empty and the {} after xField= have to be fulfilled with the field name of the longitude and the {} after yField= with the latitude. In my case, they also remain empty because my CSV is a table without field lat/lon. Then, it should be:

uri = "file://C:/Users/Simone/OneDrive/Documenti/qgis/Grass esercizi/COVID19_Fallzahlen_FL_total.csv/delimited_xy.csv?delimiter={}&xField={}&yField={}".format(os.getcwd(), ";", "x", "y")
vlayer = QgsVectorLayer(uri, "layer name you like", "delimitedtext")

But there is no right result, I obtain a CSV table without data source (with symbol triangle with "?") and I have to manually add. The error is the following:

--- Logging error ---
Traceback (most recent call last):
  File "C:\OSGEO4~1\apps\Python37\lib\logging\__init__.py", line 985, in emit
AttributeError: 'NoneType' object has no attribute 'write'
Call stack:
  File "C:/Users/Simone/AppData/Roaming/QGIS/QGIS3\profiles\mio/python/plugins\qgisnetworklogger\model.py", line 140, in request_about_to_be_created
  File "C:/Users/Simone/AppData/Roaming/QGIS/QGIS3\profiles\mio/python/plugins\qgisnetworklogger\model.py", line 327, in pop_nodes
    log.debug('Removing {} Request nodes.'.format(count))
Message: 'Removing 10 Request nodes.'
Arguments: ()

Why have I to build manually the URI? Because I don't want to install software only for this request. I prefer to reconstruct manually the URI.

So, please doesn't answer me "you can install URI builder/C and so on…".

2 Answers 2


The {} in those strings are placeholders where the .format() string method swaps in values. See: https://docs.python.org/3/library/string.html#format-string-syntax

So if you have a string like "{} {}" and call .format() on it with "Hello" and "World" as arguments, it will place them into the string in that order.

"{} {}".format("Hello", "World")

returns Hello World

In your example you are manually replacing the first one, but leaving the os.getcwd() in the format arguments. You should pull that out if you are going to hardcode the working directory in like that.

uri = "file://C:/Users/Simone/OneDrive/Documenti/qgis/Grass esercizi/COVID19_Fallzahlen_FL_total.csv/delimited_xy.csv?delimiter={}&xField={}&yField={}".format(";", "x", "y")
  • My csv.file has no x,y and so I'have changed in:
    – simone100
    Jun 5, 2020 at 20:44
  • @simone100 how are the geometry/locations stored? Jun 5, 2020 at 20:51
  • Sorry for my last uncomplete answer!! My csv.file has no x,y geometry and so right now I'have changed in: uri = "C:/Users/Simone/OneDrive/Documenti/qgis/Grass esercizi/COVID19_Fallzahlen_FL_total.csv" vlayer = QgsVectorLayer(uri, "layer name you like") QgsProject.instance().addMapLayer(vlayer)
    – simone100
    Jun 5, 2020 at 21:08
  • If my csv had had geometry fields "latitude" and "longitude" I would assume I should have to replace latitude and longitude with y and x in that way: uri = "file://C:/Users/Simone/OneDrive/Documenti/qgis/Grass esercizi/COVID19_Fallzahlen_FL_total.csv/delimited_xy.csv?delimiter={}&xField={}&yField={}".format(";", "longitude", "latitude") vlayer = QgsVectorLayer(uri, "layer name you like", "delimitedtext") QgsProject.instance().addMapLayer(vlayer) Is it right? @Jeremy Malczyk?
    – simone100
    Jun 5, 2020 at 21:11
  • @simone100 Yes, that looks right. Jun 5, 2020 at 21:18

I tried with a new csv file that has geometry point. My purpose is display the layer in the map canvas.

I did so with the new path and the file example4.csv:

uri = "file:///C:/Users/Simone/OneDrive/Documenti/qgis/dati e database/example4.csv/delimited_xy.csv?delimiter={}&xField={}&yField={}".format(";", "Longitude", "Latitude") vlayer = QgsVectorLayer(uri, "layer name you like", "delimitedtext") QgsProject.instance().addMapLayer(vlayer)

Unfortunately it does not work! The layer is not shown. I assume the reason is the lack of CRS inside the URI and other geographical information.

You see the comparison of the right URI when manually added and when added with python. I am able to reproduce with the python script only the first part of the URI, but I don't know how to add the last part of the URI that you can see in the top of the immage that is at the bottom of this message.

Someone or @Jeremy Malczyk know how to change the python script to adapt the URI at the bottom of the image to the top URI that is OK?

If I look at the QGIS manual, I don't find the solution.

URI right=OK green, URI that I am able to produce with the python script, it misses the last part and it is wrong=NO red

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.