【问题标题】:Questions about create table and transaction in sqlite3 of pythonpython的sqlite3中关于create table和transaction的问题
【发布时间】:2015-06-10 15:37:23
【问题描述】:

我正在通过 sqlite3 学习在 python 中使用 sqlite。

在关闭连接之前,应调用诸如插入、更新支持事务和 commit() 等 SQL 操作,否则数据库中不会发生任何变化。但是,“创建表”不支持事务,或者创建表是自动提交的。例如,

con.execute('create table xxx (xxxx)')

该表将立即创建。更重要的是,如果我们在创建表之前执行插入语句,而不使用 commit()。然后执行create table,insert会被提交,'create table'也会被提交。

我在文档 https://docs.python.org/2/library/sqlite3.html#sqlite3-typeshttps://www.python.org/dev/peps/pep-0249/#id3https://sqlite.org/atomiccommit.html 中没有发现任何关于此类行为的提及。

我的问题是: 1.有没有其他操作是这样的? 2. 其他 DBMS 的行为是什么? 3. 有这方面的规范吗?

【问题讨论】:

    标签: python sqlite


    【解决方案1】:

    这种行为既不是来自 SQLite(像 CREATE TABLE 这样的命令在事务中工作得很好)也不是来自 Python;它是 Python sqlite3 模块,它试图变得聪明并在某些地方插入自动事务。

    这是documented,但给出的理由相当站不住脚:

    这样做有两个原因。首先是其中一些命令在事务中不起作用。

    如果模块不会自动启动事务,则不需要在这些命令之前关闭它们。

    另一个原因是 sqlite3 需要跟踪事务状态(如果事务处于活动状态)。

    如果模块不会自动启动事务,则不需要跟踪事务状态

    请注意,DML 语句的检测并非在所有情况下都能正常工作。

    我建议通过清除 isolation_level 来禁用所有这些疯狂。

    【讨论】:

    • 谢谢。我也认为这种行为是不合理的。
    • 光标的东西也一样。打开文件后获得cursor 并永远坚持下去可以消除开销而没有任何缺点。
    【解决方案2】:

    这在过去几年发生了变化。

    在 3.6 版中更改:sqlite3 用于在 DDL 语句之前隐式提交打开的事务。现在已经不是这样了。

    让我们举个例子:

    #!/usr/bin/python
    
    import sqlite3
    import sys
    
    try:
        con = sqlite3.connect('test.db')
        cur = con.cursor()
        cur.execute("DROP TABLE IF EXISTS friends")
        cur.execute("CREATE TABLE friends(id INTEGER PRIMARY KEY, name TEXT)")
        cur.execute("INSERT INTO friends(name) VALUES ('Tom')")
        cur.execute("INSERT INTO friends(name) VALUES ('Rebecca')")
        cur.execute("INSERT INTO friends(name) VALUES ('Jim')")
        cur.execute("CREATE TABLE temp(int id)")
        cur.execute("INSERT INTO friends(nam) VALUES ('Robert')")
    
        con.commit()
    
    except sqlite3.Error as e:
    
        if con:
            con.rollback()
    
        print(f'Error {e.args[0]}:')
        sys.exit(1)
    
    finally:
    
        if con:
            con.close()
    
    

    最后一个INSERT语句有错误;列名错误。 friends 表已创建,行未插入,temp 未创建表。所以 DDL CREATE TABLE 不再提交 open 交易。

    为什么要创建friends 表呢?这是因为 Python sliqte3 模块 仅为 DML 语句(即 INSERT/UPDATE/DELETE/REPLACE)启动新事务。

    【讨论】:

      猜你喜欢
      • 2019-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-26
      相关资源
      最近更新 更多