Serializing Sqlite3 in Python

后端 未结 4 425
伪装坚强ぢ
伪装坚强ぢ 2020-12-31 02:01

To fully utilize concurrency, SQLite3 allows threads to access the same connection in three ways:

  1. Single-thread. In this mode, all mutexes are disabled and SQ
4条回答
  •  [愿得一人]
    2020-12-31 02:47

    From Verse Quiz, you might be interested in the __init__, __serve, and __fetch methods to get you started on creating a serialized SQLite3 database interface in Python. Hope that helps you further!


    import _thread
    import sqlite3
    import queue
    
    ################################################################################
    
    class Server:
    
        """Execute a protected SQLite3 database on a singular thread.
    
        Since a SQLite3 database can only accept queries on the thread that it
        was created on, this server receives requests through a queue and sends
        back the result through a list and mutex mechanism."""
    
        def __init__(self, *args):
            """Initialize the Server with a SQLite3 database thread."""
            self.__lock = _thread.allocate_lock()
            self.__lock.acquire()
            _thread.start_new_thread(self.__serve, args)
            self.__lock.acquire()
            del self.__lock
            if self.__error is not None:
                raise self.__error
            del self.__error
    
        def __serve(self, *args):
            """Run a server continuously to answer SQL queries.
    
            A SQLite3 connection is made in this thread with errors being raised
            again for the instantiator. If the connection was made successfully,
            then the server goes into a continuous loop, processing SQL queries."""
            try:
                database = sqlite3.connect(*args)
            except:
                self.__error = error = sys.exc_info()[1]
            else:
                self.__error = error = None
            self.__lock.release()
            if error is None:
                self.__QU = queue.Queue()
                while True:
                    lock, one, sql, parameters, ret = self.__QU.get()
                    try:
                        cursor = database.cursor()
                        cursor.execute(sql, parameters)
                        data = cursor.fetchone() if one else cursor.fetchall()
                        ret.extend([True, data])
                    except:
                        ret.extend([False, sys.exc_info()[1]])
                    lock.release()
    
        def fetch(self, one, sql, *parameters):
            """Execute the specified SQL query and return the results.
    
            This is a powerful shortcut method that is the closest connection
            other threads will have with the SQL server. The parameters for the
            query are dumped into a queue, and the answer is retrieved when it
            becomes available. This prevents SQLite3 from throwing exceptions."""
            lock, ret = _thread.allocate_lock(), []
            lock.acquire()
            self.__QU.put((lock, one, sql, parameters, ret))
            lock.acquire()
            if ret[0]:
                return ret[1]
            raise ret[1]
    

提交回复
热议问题