I created a map and a page layout for year 2018:

A map for year 2018

It relies on data of the table temp_desendettement_communes_2018 (from a PostGIS database).

the data table extracted for 2018

I wish using the same QGIS project for other years, and change only a parameter to choose temp_desenttement_communes_<year> as data table name for source. (and then use this parameter to correct the title of the map too).

(note: things would been simpler if year was a column of a table temp_desendettement_communes, but it's not the case)

How to declare and use a parameter in a QGIS project that applies on a table name?

  • 1
    I suppose you can't change the way that table is generated otherwise it woul'd be simplier to add a field named Year and remove it from the table name. After it's a simple use of a filter that could use a parameter.
    – Billy34
    Commented Jan 6, 2021 at 9:19
  • @Billy34 I agree with you about a Year field (I wrote it in my post), but it's not possible : the software is done that way that it only give me a table having the results of a single year, and suffixed by that year. I can't change it. Commented Jan 6, 2021 at 9:33
  • Maybe create a union query that will generate this structure. Something like SELECT *,2018 AS year FROM table_2018 UNION SELECT *,2019 AS year FROM table_2019 ...
    – Billy34
    Commented Jan 6, 2021 at 9:39
  • I think it's possible in a virtual layer
    – Billy34
    Commented Jan 6, 2021 at 9:49
  • 1
    Or save your project file as a .qgs (uncompressed) and tweak it using a text editor (database name should appear in clear text somewhere in this file). You can then prepare several qgs files for the different years
    – Billy34
    Commented Jan 6, 2021 at 10:48

1 Answer 1


You could use project-wide Macros, which does what you ask for on project load.

A very naive approach, using an input dialog to change the data source table name suffix (the year); _setYear then looks for a loaded layer with the suffix-less base_name and changes its data source (i.e. PG table name) and layer display name to base_name + year:

  • In <QGIS> | Project | Properties..., switch to Macros
    • enable Python Macros
    • replace code with
      from qgis.core import QgsProject, QgsDataSourceUri
      from PyQt5.QtWidgets import QWidget, QInputDialog, QLineEdit
      base_name = 'temp_desenttement_communes_'
      def openProject():
      def saveProject():
      def closeProject():
      def _setYear():
          popup = QWidget()
          year, ok = QInputDialog.getText(popup, "Set Source","Year:", QLineEdit.Normal, "")
          if ok and year != '':
              layers = QgsProject.instance().mapLayers().values()
              for layer in layers:
                  if layer.name().startswith(base_name):
                      provider = layer.dataProvider()
                      uri = provider.uri()
                      layer.setDataSource(uri.uri(), base_name+year, provider.name(), provider.ProviderOptions())

Save your work, reload the project and enter a new year. Pretty sure you can write a tiny Plugin with this logic to cascade the changes down to the Print Composer.

Note that you need to allow QGIS to execute Python macros; go to

  • <QGIS> | Settings | Options... and switch to General
    • choose a setting for Enable macros

Ask is fine; whenever QGIS loads the Project (or any project with macros enabled) it will ask you with a pop-up notification on the main screen for activation; if you want to switch the layer source hit Enable Macros, otherwise don't do anything.

  • 1
    To any experienced pyqgis user: feel free to improve the code in my answer to anything more sophisticated; I script in pyqgis only for these little riddles during breaks.
    – geozelot
    Commented Jan 6, 2021 at 12:52
  • Nice. I wasn't aware of such possibilities. QGis really rocks :-)
    – Billy34
    Commented Jan 6, 2021 at 16:45

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.