繁体   English   中英

如何使用 sqlite3 解锁数据库?

[英]How to unlock database with sqlite3?

我的数据库一直被锁定,我不知道为什么。

这是我的 DBHelper 类:

class DBHelper():
    def __init__(self, db = 'db1.sqlite'):
        try:
            self.conn = sqlite3.connect(db)
            self.curs = self.conn.cursor()
            print('Connection is established')
            self.conn.commit()
        except:
            return 'Connection error'
        #finally:
        #    self.conn.close()
            
    def sql_tables(self):
        self.curs.execute("CREATE TABLE IF NOT EXISTS ARTICLES(Link text PRIMARY KEY, Tittle TEXT, Time TEXT, Article TEXT)")
        self.curs.execute('CREATE TABLE IF NOT EXISTS TAGS(tag_id integer PRIMARY KEY, Tag text)')
        self.curs.execute("CREATE TABLE IF NOT EXISTS ARTICLES_TAG(Article_id text PRIMARY KEY, tag_id integer,  FOREIGN KEY (Article_id) REFERENCES ARTICLE(Link),FOREIGN KEY (tag_id) REFERENCES TAGS(tag_id))")
        self.conn.commit()

我得到OperationalError: database is locked

我该如何解决?

Sqlite 是一个很棒的数据库,但它通常旨在从单个连接中使用。 该错误提示您多次尝试打开它,或者因为您创建了多个DBHelper对象,或者因为它已被另一个进程使用。

如果你真的需要多次访问,你应该考虑使用更重的产品,比如 MariaDB 或 PostgreSQL。

如果您有多个线程试图访问同一个数据库,我建议使用线程锁。

    def __init__(self, db = 'db1.sqlite'):
        try:
            self.conn = sqlite3.connect(db)
            self.curs = self.conn.cursor()
            print('Connection is established')
            self.conn.commit()
            self.lock = threading.Lock()   # added this line
        except:
            return 'Connection error'
        
    # use this when you want to execute a line.
    # like self.execute(line)
    def execute(self, line, fetch=None):
        """
        :param line: SQL command
        :param fetch: Number to of results to return, if none or -1 returns all
        :return: The results
        """
        ret = None
        try:
            self.lock.acquire(True)  # lock
            self.cursor.execute(line)  # run command
            if not fetch or fetch == -1:
                ret = self.cursor.fetchall()
                self.data.commit()
            else:
                ret = self.cursor.fetchmany(fetch)
                self.data.commit()
            # do something
        finally:
            self.lock.release()   # release the lock after we're done
            print(f"Returning {ret}, {line}")
            return ret

    # then maybe have a function to get stuff
    def get(self, table, column, condition=None, limit=None, first=True):
        """
        :param table: database table
        :param column: What column?
        :param condition: condition of search
        :param limit: Limit the search to X results
        :param first: Return first of every result
        :return: The results
        """

        s = f"SELECT {column} FROM {table}"
        if condition: s += f" WHERE {condition}"
        if limit: s += f" LIMIT {limit}"  # create line to execute
        result = self.execute(s)  # get result
        return result if result else []  #return result

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM