I am making an application in PyQGIS that uses tables that are on an SQL server.

I want to make a copy of all those tables in a local Geopackage, because I want to use my application in my laptop when there is no possibility to connect to the server.

First I tried to do it with my Method 1, which is using the option to write a new file with

QgsVectorFileWriter.writeAsVectorFormatV2(vlayer_ori, db_dest[0], transform_context, save_options)

This option works great with a table that has points.

But there are two cases where it doesn't work well:

  1. With a table that has lines, it copies the data, but Qgis does not show the lines, Qgis think that the table only contains data and not geometries.

  2. With a table with no Geometries:

    • With method 1 don't copy anything.
    • That is why I created method 2, in which, for make the copy, I use the function:


      This also don't copy anything.

When I load Table with no geometry, if I ask vlayer_ori.featureCount() say there 3 features.

But if I do "for feat in vlayer_ori.getFeatures()", the for don't do anything because no feature is returned.

Any idea, what is happening, why getFeatures() not return anything is there is no geometry, but there are attributes?

Here is my complete code:

The Code for Open Database is:

    uri = QgsDataSourceUri()           
    uri.setConnection(server,"", data_base, user, pss)
    for db in self.ddbb:
        ddbb_to_copy.append(uri.uri(), "mssql") 
    return ddbb_to_copy
  for i in range(len(DDBB_origin)):  # FOR EACH TABLE IN DATABASE ORIGIN MAKE THIS FOR

        # Load Data Bases Properties [uri (File Name), "ogr" or "mssql",Table Name]

        vlayer_ori = QgsVectorLayer(db_ori[0],'Layer Origin', db_ori[1])
        if not vlayer_ori.isValid():
            info("SQL Layer failed to load! way ")
            info('Correct Load ')

        if db_dest[1]=='ogr' and vlayer_ori.isSpatial()
            # If there are Geometies in Dabta Base do this 
            # METHOD 1 OF COPY - WITH QgsVectorFileWriter

            info('Origin is Spacial'+vlayer_ori.isSpatial())
            info('Number of Features in Layer'+vlayer_ori.featureCount())

            save_options = QgsVectorFileWriter.SaveVectorOptions() 
            save_options.fileEncoding = "UTF-8"
            save_options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
            save_options.EditionCapability = QgsVectorFileWriter.CanAddNewLayer                  
            save_options.layerName = db_dest[2]
            transform_context = QgsProject.instance().transformContext()

            # If there aren't any  Geometies in Data Base do this 
            # METHOD 2 OF COPY - WITH layer.dataProvider().addFeatures

            # Load Destiny Data  
            vlayer_dest = QgsVectorLayer(db_dest[0],'Layer Dest', db_dest[1])
            if not vlayer_dest.isValid():
                self.parent.info("SQL Layer failed to load! way "+db_dest[0])
                self.parent.info('Correct Load SQL '+db_dest[0])

            # Delete Previous Data
            for f in vlayer_dest.getFeatures():

            # Add Data
            print('Features in Origin Table ',vlayer_ori.featureCount())    # RETURN 3 FEATURES
            for feat in vlayer_ori.getFeatures():                           # NEVER DO THIS FOR
                print (count)

            print('Features in Destination Table ',vlayer_dest.featureCount())   # 0 FEATURES IN DESTINY TABLE

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.