Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Multiple connections to in-memory QSqlDatabase
Forum Update on Monday, May 27th 2025

Multiple connections to in-memory QSqlDatabase

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 2.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    bepaald
    wrote on 17 Jan 2019, 17:57 last edited by
    #1

    Hi! I'm trying to open a second connection to a sql database that is only in memory. When trying to use QSqlDatabase::cloneDatabase(), I get no errors, but an empty database. Running the following:

    #include <QtSql>
    #include <QStringList>
    #include <QDebug>
    
    int main()
    {
      // create sql database
      QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
      db.setDatabaseName(":memory:"); /* *** */
      qDebug() << "Opening original database: " << db.open();
    
      // add some tables
      QSqlQuery query;
      query.exec("CREATE TABLE table1 (_id INTEGER PRIMARY KEY)");
      query.exec("CREATE TABLE table2 (_id INTEGER PRIMARY KEY)");
    
      qDebug() << "Tables in original: " << db.tables();
    
      // try to clone connection...
      QSqlDatabase clone = QSqlDatabase::cloneDatabase(db, "clone");
      qDebug() << "Opening clone: " << clone.open();
      qDebug() << "Tables in clone: " << clone.tables();
    
      return 0;
    }
    

    Output is

    [~/sqltest] $ ./sqltest 
    Opening original database:  true
    Tables in original:  ("table1", "table2")
    Opening clone:  true
    Tables in clone:  ()
    [~/sqltest] $
    

    When changing the setDatabaseName() call to any temporary filename, output is as expected:

    [~/sqltest] $ ./sqltest 
    Opening original database:  true
    Tables in original:  ("table1", "table2")
    Opening clone:  true
    Tables in clone:  ("table1", "table2")
    [~/sqltest] $ 
    

    Am I doing something stupid? Or is this just not possible? Any way around it?

    Thanks!

    J 1 Reply Last reply 17 Jan 2019, 18:45
    0
    • B bepaald
      17 Jan 2019, 19:50

      @Christian-Ehrlicher

      Thanks! I had tried to call db.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE") before, but since it had no effect, I removed it to keep the posted code as compact as possible.

      According to the page you linked 'In-memory databases are allowed to use shared cache if they are opened using a URI filename.', that is, they must be opened with "file::memory:" instead of just ":memory:". However, when I try to use this URI filename by calling setDataBaseName("file::memory:") just creates an on-disk database called "file::memory:", so no luck.

      @JonB

      In my application a database is created and filled, much like in the example code. Later in the program, I would like to run queries on this database from another thread. For this I need to open a new connection to this db from that thread, since existing connections can only be used from the thread they were opened in. I think there are probably some other workarounds for this problem, but they will all take a lot more effort than if this just worked. The database does not need to be saved after the program exits and might in fact contain sensitive information, so I would like to avoid touching the disk if possible.
      Using setDataBaseName("") seems to behave the same as using ":memory:", so still no luck.

      B Offline
      B Offline
      bepaald
      wrote on 17 Jan 2019, 19:56 last edited by
      #6

      Nevermind, I got it. To enable an URI database name, I also had to set the QSQLITE_OPEN_URI option. So calling setConnectOptions("QSQLITE_OPEN_URI;QSQLITE_ENABLE_SHARED_CACHE") and setDatabaseName("file::memory:") everything seems to behave as I hoped (at least in this minimal example).

      Thanks!

      1 Reply Last reply
      2
      • B bepaald
        17 Jan 2019, 17:57

        Hi! I'm trying to open a second connection to a sql database that is only in memory. When trying to use QSqlDatabase::cloneDatabase(), I get no errors, but an empty database. Running the following:

        #include <QtSql>
        #include <QStringList>
        #include <QDebug>
        
        int main()
        {
          // create sql database
          QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
          db.setDatabaseName(":memory:"); /* *** */
          qDebug() << "Opening original database: " << db.open();
        
          // add some tables
          QSqlQuery query;
          query.exec("CREATE TABLE table1 (_id INTEGER PRIMARY KEY)");
          query.exec("CREATE TABLE table2 (_id INTEGER PRIMARY KEY)");
        
          qDebug() << "Tables in original: " << db.tables();
        
          // try to clone connection...
          QSqlDatabase clone = QSqlDatabase::cloneDatabase(db, "clone");
          qDebug() << "Opening clone: " << clone.open();
          qDebug() << "Tables in clone: " << clone.tables();
        
          return 0;
        }
        

        Output is

        [~/sqltest] $ ./sqltest 
        Opening original database:  true
        Tables in original:  ("table1", "table2")
        Opening clone:  true
        Tables in clone:  ()
        [~/sqltest] $
        

        When changing the setDatabaseName() call to any temporary filename, output is as expected:

        [~/sqltest] $ ./sqltest 
        Opening original database:  true
        Tables in original:  ("table1", "table2")
        Opening clone:  true
        Tables in clone:  ("table1", "table2")
        [~/sqltest] $ 
        

        Am I doing something stupid? Or is this just not possible? Any way around it?

        Thanks!

        J Offline
        J Offline
        JonB
        wrote on 17 Jan 2019, 18:45 last edited by
        #2

        @bepaald

        I'm trying to open a second connection to a sql database that is only in memory.

        I read elsewhere hints like

        As far as I know , the scenario of having different connections in each thread to the same physical file
        is not applicable to in-memory database because you can not open several connections to the same in-memory
        database.

        The suggestion is: why do you need to do this?

        J 1 Reply Last reply 17 Jan 2019, 18:57
        0
        • C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 17 Jan 2019, 18:47 last edited by
          #3

          According to https://www.sqlite.org/inmemorydb.html the database must be opened in 'shared mode'.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          B 1 Reply Last reply 17 Jan 2019, 19:50
          3
          • J JonB
            17 Jan 2019, 18:45

            @bepaald

            I'm trying to open a second connection to a sql database that is only in memory.

            I read elsewhere hints like

            As far as I know , the scenario of having different connections in each thread to the same physical file
            is not applicable to in-memory database because you can not open several connections to the same in-memory
            database.

            The suggestion is: why do you need to do this?

            J Offline
            J Offline
            JonB
            wrote on 17 Jan 2019, 18:57 last edited by JonB
            #4

            @JonB
            From @Christian-Ehrlicher 's link I see:

            hence is very little difference between a pure in-memory database created by ":memory:" and a temporary database created by an empty filename

            You could try that and see if it behaves more like you want when you used your own "temporary filenames", which you say worked. Or it might exhibit the same problem...

            1 Reply Last reply
            0
            • C Christian Ehrlicher
              17 Jan 2019, 18:47

              According to https://www.sqlite.org/inmemorydb.html the database must be opened in 'shared mode'.

              B Offline
              B Offline
              bepaald
              wrote on 17 Jan 2019, 19:50 last edited by bepaald
              #5

              @Christian-Ehrlicher

              Thanks! I had tried to call db.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE") before, but since it had no effect, I removed it to keep the posted code as compact as possible.

              According to the page you linked 'In-memory databases are allowed to use shared cache if they are opened using a URI filename.', that is, they must be opened with "file::memory:" instead of just ":memory:". However, when I try to use this URI filename by calling setDataBaseName("file::memory:") just creates an on-disk database called "file::memory:", so no luck.

              @JonB

              In my application a database is created and filled, much like in the example code. Later in the program, I would like to run queries on this database from another thread. For this I need to open a new connection to this db from that thread, since existing connections can only be used from the thread they were opened in. I think there are probably some other workarounds for this problem, but they will all take a lot more effort than if this just worked. The database does not need to be saved after the program exits and might in fact contain sensitive information, so I would like to avoid touching the disk if possible.
              Using setDataBaseName("") seems to behave the same as using ":memory:", so still no luck.

              B 1 Reply Last reply 17 Jan 2019, 19:56
              0
              • B bepaald
                17 Jan 2019, 19:50

                @Christian-Ehrlicher

                Thanks! I had tried to call db.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE") before, but since it had no effect, I removed it to keep the posted code as compact as possible.

                According to the page you linked 'In-memory databases are allowed to use shared cache if they are opened using a URI filename.', that is, they must be opened with "file::memory:" instead of just ":memory:". However, when I try to use this URI filename by calling setDataBaseName("file::memory:") just creates an on-disk database called "file::memory:", so no luck.

                @JonB

                In my application a database is created and filled, much like in the example code. Later in the program, I would like to run queries on this database from another thread. For this I need to open a new connection to this db from that thread, since existing connections can only be used from the thread they were opened in. I think there are probably some other workarounds for this problem, but they will all take a lot more effort than if this just worked. The database does not need to be saved after the program exits and might in fact contain sensitive information, so I would like to avoid touching the disk if possible.
                Using setDataBaseName("") seems to behave the same as using ":memory:", so still no luck.

                B Offline
                B Offline
                bepaald
                wrote on 17 Jan 2019, 19:56 last edited by
                #6

                Nevermind, I got it. To enable an URI database name, I also had to set the QSQLITE_OPEN_URI option. So calling setConnectOptions("QSQLITE_OPEN_URI;QSQLITE_ENABLE_SHARED_CACHE") and setDatabaseName("file::memory:") everything seems to behave as I hoped (at least in this minimal example).

                Thanks!

                1 Reply Last reply
                2

                4/6

                17 Jan 2019, 18:57

                • Login

                • Login or register to search.
                4 out of 6
                • First post
                  4/6
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved