Python sqlite3 and concurrency

前端 未结 14 784
南笙
南笙 2020-11-30 18:00

I have a Python program that uses the \"threading\" module. Once every second, my program starts a new thread that fetches some data from the web, and stores this data to my

相关标签:
14条回答
  • 2020-11-30 18:31

    The following found on mail.python.org.pipermail.1239789

    I have found the solution. I don't know why python documentation has not a single word about this option. So we have to add a new keyword argument to connection function and we will be able to create cursors out of it in different thread. So use:

    sqlite.connect(":memory:", check_same_thread = False)
    

    works out perfectly for me. Of course from now on I need to take care of safe multithreading access to the db. Anyway thx all for trying to help.

    0 讨论(0)
  • 2020-11-30 18:33

    Contrary to popular belief, newer versions of sqlite3 do support access from multiple threads.

    This can be enabled via optional keyword argument check_same_thread:

    sqlite.connect(":memory:", check_same_thread=False)
    
    0 讨论(0)
  • 2020-11-30 18:33

    You need to use session.close() after every transaction to the database in order to use the same cursor in the same thread not using the same cursor in multi-threads which cause this error.

    0 讨论(0)
  • 2020-11-30 18:34

    The most likely reason you get errors with locked databases is that you must issue

    conn.commit()
    

    after finishing a database operation. If you do not, your database will be write-locked and stay that way. The other threads that are waiting to write will time-out after a time (default is set to 5 seconds, see http://docs.python.org/2/library/sqlite3.html#sqlite3.connect for details on that).

    An example of a correct and concurrent insertion would be this:

    import threading, sqlite3
    class InsertionThread(threading.Thread):
    
        def __init__(self, number):
            super(InsertionThread, self).__init__()
            self.number = number
    
        def run(self):
            conn = sqlite3.connect('yourdb.db', timeout=5)
            conn.execute('CREATE TABLE IF NOT EXISTS threadcount (threadnum, count);')
            conn.commit()
    
            for i in range(1000):
                conn.execute("INSERT INTO threadcount VALUES (?, ?);", (self.number, i))
                conn.commit()
    
    # create as many of these as you wish
    # but be careful to set the timeout value appropriately: thread switching in
    # python takes some time
    for i in range(2):
        t = InsertionThread(i)
        t.start()
    

    If you like SQLite, or have other tools that work with SQLite databases, or want to replace CSV files with SQLite db files, or must do something rare like inter-platform IPC, then SQLite is a great tool and very fitting for the purpose. Don't let yourself be pressured into using a different solution if it doesn't feel right!

    0 讨论(0)
  • 2020-11-30 18:38

    Scrapy seems like a potential answer to my question. Its home page describes my exact task. (Though I'm not sure how stable the code is yet.)

    0 讨论(0)
  • 2020-11-30 18:38

    I would take a look at the y_serial Python module for data persistence: http://yserial.sourceforge.net

    which handles deadlock issues surrounding a single SQLite database. If demand on concurrency gets heavy one can easily set up the class Farm of many databases to diffuse the load over stochastic time.

    Hope this helps your project... it should be simple enough to implement in 10 minutes.

    0 讨论(0)
提交回复
热议问题