Versuchen Sie es mit APSW, einer Python-Bibliothek, die SQLite ernst nehmen kann

Hintergrund

Bei Verwendung von SQLite aus Python ist sqlite3 standardmäßig in Python 2.5 und höher verfügbar.

Es bietet eine SQL-Schnittstelle, die der DB-API 2.0-Spezifikation entspricht und unter dem Namen pysqlite entwickelt wurde.

sqlite3 http://docs.python.jp/2/library/sqlite3.html

Diese Bibliothek verfügt jedoch nicht über alle Funktionen von SQLite. Dies entspricht den DB-API-Spezifikationen.

APSW ist eine Bibliothek, mit der Sie die SQLite-API in Python vollständig nutzen können. APSW funktioniert mit Python 2.x und Python 3.x.

https://github.com/rogerbinns/apsw http://rogerbinns.github.io/apsw/

Wie installiert man

Die Installation ist mit pip oder easy_install nicht möglich.

** Update 2019.08.03 ** Derzeit kann es auch unten installiert werden.

pip install --user https://github.com/rogerbinns/apsw/releases/download/3.28.0-r1/apsw-3.28.0-r1.zip --global-option=fetch --global-option=--version --global-option=3.28.0 --global-option=--all --global-option=build --global-option=--enable-all-extensions

Die neuesten Informationen finden Sie weiter unten. https://rogerbinns.github.io/apsw/download.html#easy-install-pip-pypi

Für Windows

Laden Sie die entsprechende Binärdatei aus dem Folgenden herunter und führen Sie das Installationsprogramm aus.

http://rogerbinns.github.io/apsw/download.html#source-and-binaries

Wenn Sie über Visual Studio verfügen, können Sie genau wie UNIX aus dem Quellcode erstellen. (Mit mingw32 konnte ich es erstellen, aber es funktionierte nicht, da zur Laufzeit keine DLL vorhanden war.)

Für Unix

Laden Sie den Quellcode herunter und führen Sie den folgenden Befehl aus.

python setup.py fetch --all build --enable-all-extensions install

Details zum Build finden Sie auf der folgenden Seite. http://rogerbinns.github.io/apsw/build.html

Unterschied zwischen APSW und Pysqlite

APSW und Pysqlite bieten Zugriff auf SQLite aus radikal unterschiedlichen Richtungen.

APSW umschließt nur Version 3 von SQLite und bietet eine Möglichkeit, auf alle APIs zuzugreifen.

pysqlite verhält sich wie jede andere Datenbank, um einen DBAPI-kompatiblen Wrapper bereitzustellen. Daher werden einige SQLite-Funktionen ausgeblendet.

Im Folgenden finden Sie einige der Vorteile und erweiterten Funktionen von APSW.

Sie können die neuesten SQLite-Funktionen verwenden

APSW stellt die neueste Version von SQLite zur Verfügung. Wenn Features zu SQLite hinzugefügt oder geändert werden, folgt APSW auch diesen Features.

Virtuelle Tabelle ist verfügbar.

Virtuelle Tabelle ist eine in SQLite 3.3.7 eingeführte Funktion.

Virtuelle Tabellen unterscheiden sich in Bezug auf SQL-Anweisungen nicht von anderen Tabellen und Ansichten. Hinter den Kulissen lösen Abfragen und Schreibvorgänge in Virtual Table Rückrufmethoden aus, anstatt Datenbankdateien zu lesen und zu schreiben.

Das folgende Beispiel zeigt die Bearbeitung von Daten in einem zweidimensionalen Array mit SQL.

# -*- coding: utf-8 -*- 
import os, sys, time
import apsw
connection=apsw.Connection(":memory:")
cursor=connection.cursor()

###
### Virtual tables
### 

#
data = [
    [1, 'test1', 'categoryA'],
    [2, 'test2', 'categoryA'],
    [3, 'test3', 'categoryA'],
    [4, 'test4', 'categoryB'],
    [5, 'test5', 'categoryB'],
    [6, 'test6', 'categoryB'],
    [7, 'test7', 'categoryB'],
    [8, 'test8', 'categoryC'],
    [9, 'test9', 'categoryC'],
    [10, 'test10', 'categoryC']
]
counter = len(data)


# This gets registered with the Connection
class Source:
    def Create(self, db, modulename, dbname, tablename, *args):
        columns = ['rowid', 'name', 'category']
        schema="create table foo("+','.join(["'%s'" % (x,) for x in columns[1:]])+")"
        return schema,Table(columns,data)
    Connect=Create

# Represents a table
class Table:
    def __init__(self, columns, data):
        self.columns=columns
        self.data=data

    def BestIndex(self, *args):
        return None

    def Open(self):
        return Cursor(self)

    def Disconnect(self):
        pass

    def UpdateChangeRow(self, row, newrowid, fields):
        for d in data:
            if(d[0] == row):
                d[0] = newrowid
                d[1] = fields[0]
                d[2] = fields[1]

    def UpdateDeleteRow(self, row):
        for i in range(len(data)):
            if(data[i][0] == row):
                del data[i]
                return

    def UpdateInsertRow(self, rowid, fields):
        global counter
        counter = counter + 1
        data.append([counter, fields[0], fields[1]])
        return counter

    Destroy=Disconnect

# Represents a cursor
class Cursor:
    def __init__(self, table):
        self.table=table

    def Filter(self, *args):
        self.pos=0

    def Eof(self):
        return self.pos>=len(self.table.data)

    def Rowid(self):
        return self.table.data[self.pos][0]

    def Column(self, col):
        return self.table.data[self.pos][1+col]

    def Next(self):
        self.pos+=1

    def Close(self):
        pass

connection.createmodule("source", Source())
cursor.execute("create virtual table test using source()")
ret = cursor.execute("select * from test where category = 'categoryB'")
for row in ret:
    print row[0], row[1]
print ('update -----------------')
cursor.execute("update test set category='categoryB' where name='test1'")
ret = cursor.execute("select * from test where category = 'categoryB'")
for row in ret:
    print row[0], row[1]

print ('delete -----------------')
cursor.execute("delete from test where name='test4'")
ret = cursor.execute("select * from test")
for row in ret:
    print row[0], row[1]

print ('insert ----------------')
cursor.execute("insert into test values('xxxx','yyyy')")
ret = cursor.execute("select * from test")
for row in ret:
    print row[0], row[1]

Auf diese Weise können Sie mithilfe von VirutalTable beliebige Daten mit SQL bearbeiten. Im offiziellen Beispiel gibt es ein Beispiel, das die Dateien im Verzeichnis mit SQL auswählt. http://apidoc.apsw.googlecode.com/hg/example.html

Weitere Informationen zu VirtualTable finden Sie im Folgenden. http://rogerbinns.github.io/apsw/vtable.html

Virtual File System (VFS) ist verfügbar

Sie können VFS verwenden, das die Schnittstelle zwischen dem Kern und den zugrunde liegenden Betriebssystemen von SQLite definiert.

Mit APSW können Sie die VFS-Funktionalität nutzen und das Standard-VFS erben und erweitern. Im folgenden Beispiel wird beispielsweise VFS verwendet, um eine SQLite-Datei zu verschleiern.

# -*- coding: utf-8 -*- 
import os, sys, time
import apsw

###Dieses Beispiel ist ein Auszug aus dem Folgenden
### http://apidoc.apsw.googlecode.com/hg/example.html
###Verschleiern Sie die Datenbank mit VFS
###XOR alle Bytes des Schemas mit 0xa5.
###Diese Methode wird von MAPI und SQL Server verwendet
###

def encryptme(data):
    if not data: return data
    return "".join([chr(ord(x)^0xa5) for x in data])

# ""Die Vererbung von der Basis von ist das Standard-VFS
class ObfuscatedVFS(apsw.VFS):
    def __init__(self, vfsname="obfu", basevfs=""):
        self.vfsname=vfsname
        self.basevfs=basevfs
        apsw.VFS.__init__(self, self.vfsname, self.basevfs)

    #Ich möchte meine eigene Datei implementieren, aber ich möchte sie auch erben
    def xOpen(self, name, flags):
        # We can look at uri parameters
        if isinstance(name, apsw.URIFilename):
            print "fast is", name.uri_parameter("fast")
            print "level is", name.uri_int("level", 3)
            print "warp is", name.uri_boolean("warp", False)
            print "notpresent is", name.uri_parameter("notpresent")
        return ObfuscatedVFSFile(self.basevfs, name, flags)

#Überschreiben Sie xRead und xWrite, um Kryptoroutinen zu implementieren
class ObfuscatedVFSFile(apsw.VFSFile):
    def __init__(self, inheritfromvfsname, filename, flags):
        apsw.VFSFile.__init__(self, inheritfromvfsname, filename, flags)

    def xRead(self, amount, offset):
        return encryptme(super(ObfuscatedVFSFile, self).xRead(amount, offset))

    def xWrite(self, data, offset):
        super(ObfuscatedVFSFile, self).xWrite(encryptme(data), offset)


# To register the VFS we just instantiate it
obfuvfs=ObfuscatedVFS()
# Lets see what vfs are now available?
print apsw.vfsnames()

# Make an obfuscated db, passing in some URI parameters
obfudb=apsw.Connection("file:myobfudb?fast=speed&level=7&warp=on",
                       flags=apsw.SQLITE_OPEN_READWRITE | apsw.SQLITE_OPEN_CREATE | apsw.SQLITE_OPEN_URI,
                       vfs=obfuvfs.vfsname)
# Check it works
obfudb.cursor().execute("create table foo(x,y); insert into foo values(1,2)")

#Überprüfen Sie den Inhalt der tatsächlichen Disc
print `open("myobfudb", "rb").read()[:20]`
# '\xf6\xf4\xe9\xcc\xd1\xc0\x85\xc3\xca\xd7\xc8\xc4\xd1\x85\x96\xa5\xa1\xa5\xa4\xa4'

print `encryptme(open("myobfudb", "rb").read()[:20])`
# 'SQLite format 3\x00\x04\x00\x01\x01'

# Tidy up
obfudb.close()
os.remove("myobfudb")

Siehe unten für Details. http://rogerbinns.github.io/apsw/vfs.html

BLOB-E / A verfügbar

Blob ist ein SQLite-Datentyp, der eine Folge von Bytes darstellt. Es ist ein Byte der Größe Null oder größer.

Sie können diesen Blob mit APSW lesen und schreiben. Das Verwendungsbeispiel ist unten dargestellt.

# -*- coding: utf-8 -*- 
import os, sys, time
import apsw
import os
connection=apsw.Connection("blob.sqlite")
cursor=connection.cursor()

###
### Blob I/O
### http://apidoc.apsw.googlecode.com/hg/example.html

cursor.execute("create table blobby(x,y)")
# Add a blob we will fill in later
cursor.execute("insert into blobby values(1,zeroblob(10000))")
# Or as a binding
cursor.execute("insert into blobby values(2,?)", (apsw.zeroblob(20000),))
# Open a blob for writing.  We need to know the rowid
rowid=cursor.execute("select ROWID from blobby where x=1").next()[0]
blob=connection.blobopen("main", "blobby", "y", rowid, 1) # 1 is for read/write
blob.write("hello world")
blob.seek(100)
blob.write("hello world, again")
blob.close()

Weitere Informationen finden Sie im Folgenden. http://rogerbinns.github.io/apsw/blob.html

Backup verfügbar

APSW kann die Sicherung verwenden, um eine verbundene Datenbank in einer anderen verbundenen Datenbank zu sichern.

# -*- coding: utf-8 -*- 
import os, sys, time
import apsw
import os
connection=apsw.Connection("src.sqlite")
cursor=connection.cursor()

#Erstellen Sie eine Sicherungsquelle
cursor.execute("create table test(x,y)")
cursor.execute("insert into test values(1,'TEST1')")
cursor.execute("insert into test values(2,'TEST2')")
cursor.execute("insert into test values(3,'TEST3')")
cursor.execute("insert into test values(4,'TEST4')")
cursor.execute("insert into test values(5,'TEST5')")

#Backup
memcon=apsw.Connection("backup.sqlite")
with memcon.backup("main", connection, "main") as backup:
    backup.step() # copy whole database in one go

for row in memcon.cursor().execute("select * from test"):
    print row[0], row[1]
    pass

Weitere Informationen finden Sie im Folgenden. http://rogerbinns.github.io/apsw/backup.html

Kann über Gewinde betrieben werden

Sie können Verbindungen und Cursor über Threads hinweg gemeinsam nutzen. Für pysqlite müssen Connection und Cursor im selben Thread verwendet werden.

Pysqlite Beispiel


# -*- coding: utf-8 -*- 
import threading
import sqlite3
def func(t):
    return 1 + t


class TestThread(threading.Thread):
    def __init__(self, conn):
        threading.Thread.__init__(self)
        self.conn = conn

    def run(self):
        self.conn.create_function("func", 1, func)
        cur = self.conn.cursor()
        ret = cur.execute("select func(3)")
        for row in ret:
            print(row[0])


conn = sqlite3.connect(":memory:")
th = TestThread(conn)
th.start()
th.join()

Da pysqlite keine Cross-Thread-Operationen zulässt, treten die folgenden Ausnahmen auf.

Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\Python27\lib\threading.py", line 810, in __bootstrap_inner
    self.run()
  File "test_thread.py", line 14, in run
    self.conn.create_function("func", 1, func)
ProgrammingError: SQLite objects created in a thread can only be used in that sa
me thread.The object was created in thread id 19540 and this is thread id 4652

Im Fall von APSW wird keine Ausnahme für ähnliche Threads ausgelöst.

Spreizgewinde mit APSW


# -*- coding: utf-8 -*- 
import threading
import apsw


def func(t):
    return 1 + t


class TestThread(threading.Thread):
    def __init__(self, conn):
        threading.Thread.__init__(self)
        self.conn = conn

    def run(self):
        self.conn.createscalarfunction("func", func, 1)
        cur = self.conn.cursor()
        ret = cur.execute("select func(3)")
        for row in ret:
            print(row[0])


conn = apsw.Connection(":memory:")
th = TestThread(conn)
th.start()
th.join()

Wenn Sie die exklusive Verarbeitung jedoch nicht sorgfältig behandeln, führt dies zu einem Absturz oder einer Deadlock.

Verwendung verschachtelter Transaktionen

Mit APSW können Sie verschachtelte Transaktionen mithilfe des Kontextmanagers von Connection verwenden. In pysqlite kann jeweils nur eine Transaktion verwendet werden, und eine Verschachtelung ist nicht möglich.

Der in dieser verschachtelten Transaktion verwendete SavePoint wurde in SQLite 3.6.8 hinzugefügt. Dies ist einer der Vorteile von APSW, mit dem Sie SQLite aktuell verwenden können.

Das Folgende ist ein Beispiel für verschachtelte Transaktionen.

# -*- coding: utf-8 -*- 
import os, sys, time
import apsw
import os
connection=apsw.Connection(":memory:")

connection.cursor().execute("create table test(x primary key,y)")
with connection: #Starten Sie eine Transaktion mit mit. Rollback mit Ausnahmen, sonst Commit
    connection.cursor().execute("insert into test values(1,'TEST1')")
    try: #Starten Sie SAVE POINT mit mit. Rollback mit Ausnahmen, sonst Commit
        with connection:
            connection.cursor().execute("insert into test values(2,'TEST2')")
            connection.cursor().execute("insert into test values(3,'TEST3')")
    except Exception, ex:
        print (ex)
        print ('rollback 1')
    try:
        with connection: #Die folgende SQL wird nicht mit einem Fehler aufgezeichnet
            connection.cursor().execute("insert into test values(4,'TEST4')")
            connection.cursor().execute("insert into test values(4,'Error')")
    except Exception, ex:
        print (ex)
        print ('rollback 2')
    try:
        with connection:
            connection.cursor().execute("insert into test values(5,'TEST5')")
            connection.cursor().execute("insert into test values(6,'TEST6')")
    except Exception, ex:
        print (ex)
        print ('rollback 3')

for row in connection.cursor().execute("select * from test"):
    print row[0], row[1]

** Informationen zum Verbindungskontext ** http://rogerbinns.github.io/apsw/connection.html#apsw.Connection.enter

** Informationen zu verschachtelten SQLite-Transaktionen ** https://sqlite.org/lang_savepoint.html

Ausführung mehrerer Befehle

In APSW können mehrere Befehle ausgeführt werden, indem sie durch ein Semikolon getrennt werden.

# -*- coding: utf-8 -*- 
import apsw
con=apsw.Connection(":memory:")
cur=con.cursor()
for row in cur.execute("create table foo(x,y,z);insert into foo values (?,?,?);"
                       "insert into foo values(?,?,?);select * from foo;drop table foo;"
                       "create table bar(x,y);insert into bar values(?,?);"
                       "insert into bar values(?,?);select * from bar;",
                       (1,2,3,4,5,6,7,8,9,10)):
                           print row

SQL, das Daten wie SELECT zurückgibt, ist in Cursor.executemany () verfügbar.

In APSW ist SQL, das Daten wie SELECT zurückgibt, in Cursor.executemany () verfügbar.

# -*- coding: utf-8 -*- 
import apsw
con=apsw.Connection(":memory:")
cur=con.cursor()
cur.execute("create table foo(x);")
cur.executemany("insert into foo (x) values(?)", ( [1], [2], [3] ) )

# You can also use it for statements that return data
for row in cur.executemany("select * from foo where x=?", ( [1], [2], [3] ) ):
    print row

In pysqlite kann executemany () in SQL einschließlich SELECT nicht verwendet werden. http://stackoverflow.com/questions/14142554/sqlite3-python-executemany-select

Einfache Verfolgung von Fehlern bei Rückrufen

APSW gibt eine leicht nachvollziehbare Ausnahme aus, z. B. wenn innerhalb einer benutzerdefinierten Funktion ein Fehler auftritt.

Lassen Sie uns unten den Unterschied überprüfen, wenn eine Ausnahme in einer benutzerdefinierten Funktion ausgelöst wird.

Pysqlite-Ausnahme


import sqlite3
def badfunc(t):
    return 1/0

#sqlite3.enable_callback_tracebacks(True)
con = sqlite3.connect(":memory:")
con.create_function("badfunc", 1, badfunc)
cur = con.cursor()
cur.execute("select badfunc(3)")

Wenn enable_callback_tracebacks False ist (Standard), wird der folgende Fehler angezeigt:

Traceback (most recent call last):
  File "test_fnc1.py", line 9, in <module>
    cur.execute("select badfunc(3)")
sqlite3.OperationalError: user-defined function raised exception

Wenn enable_callback_tracebacks True ist, tritt der folgende Fehler auf.

Traceback (most recent call last):
  File "test_fnc1.py", line 3, in badfunc
    return 1/0
ZeroDivisionError: integer division or modulo by zero
Traceback (most recent call last):
  File "test_fnc1.py", line 9, in <module>
    cur.execute("select badfunc(3)")
sqlite3.OperationalError: user-defined function raised exception

Wenn enable_callback_tracebacks False ist, werden die Ausnahmen in der benutzerdefinierten Funktion gequetscht, und selbst wenn dies auf True gesetzt ist, ist die Art und Weise, wie Traceback angezeigt wird, nicht intuitiv.

Schauen wir uns auf der anderen Seite die Ausnahme von APSW an.

Ausnahme in APSW


def badfunc(t):
    return 1/0


import apsw
con = apsw.Connection(":memory:")
con.createscalarfunction("badfunc", badfunc, 1)
cur = con.cursor()
cur.execute("select badfunc(3)")

APSW gibt Traceback aus, das intuitiv wie folgt leicht zu verstehen ist.

Traceback (most recent call last):
  File "test_fnc2.py", line 9, in <module>
    cur.execute("select badfunc(3)")
  File "c:\apsw\src\connection.c", line 2021, in user-defined-scalar-badfunc
  File "test_fnc2.py", line 2, in badfunc
    return 1/0
ZeroDivisionError: integer division or modulo by zero

Bericht von APSW Trace kann ausgegeben werden

APSW Trace verfolgt problemlos die SQL-Ausführung, ohne Ihren Code zu ändern, und bietet einen zusammenfassenden Bericht.

APSW Trace befindet sich im Ordner tools im folgenden Quellcode. http://rogerbinns.github.io/apsw/download.html#source-and-binaries

** Ausführungsmethode **

$ python /path/to/apswtrace.py [apswtrace options] yourscript.py [your options]

** Ausführungsbeispiel ** Das folgende Beispiel zeigt das Anfordern eines Berichts des Skripts, das unter "Verwenden verschachtelter Transaktionen" verwendet wird.

C:\dev\python\apsw>python apswtrace.py --sql --rows --timestamps --thread test_n
est.py
290e5c0 0.002 1734 OPEN: "" win32 READWRITE|CREATE
292aad8 0.009 1734 CURSORFROM: 290e5c0 DB: ""
292aad8 0.010 1734 SQL: create table test(x primary key,y)
290e5c0 0.012 1734 SQL: SAVEPOINT "_apsw-0"
292aad8 0.013 1734 CURSORFROM: 290e5c0 DB: ""
292aad8 0.015 1734 SQL: insert into test values(1,'TEST1')
290e5c0 0.016 1734 SQL: SAVEPOINT "_apsw-1"
292aad8 0.018 1734 CURSORFROM: 290e5c0 DB: ""
292aad8 0.019 1734 SQL: insert into test values(2,'TEST2')
292aad8 0.021 1734 CURSORFROM: 290e5c0 DB: ""
292aad8 0.022 1734 SQL: insert into test values(3,'TEST3')
290e5c0 0.023 1734 SQL: RELEASE SAVEPOINT "_apsw-1"
290e5c0 0.025 1734 SQL: SAVEPOINT "_apsw-1"
292ab10 0.026 1734 CURSORFROM: 290e5c0 DB: ""
292ab10 0.028 1734 SQL: insert into test values(4,'TEST4')
292ab10 0.029 1734 CURSORFROM: 290e5c0 DB: ""
292ab10 0.031 1734 SQL: insert into test values(4,'Error')
290e5c0 0.032 1734 SQL: ROLLBACK TO SAVEPOINT "_apsw-1"
290e5c0 0.034 1734 SQL: RELEASE SAVEPOINT "_apsw-1"
ConstraintError: UNIQUE constraint failed: test.x
rollback 2
290e5c0 0.038 1734 SQL: SAVEPOINT "_apsw-1"
292ab48 0.040 1734 CURSORFROM: 290e5c0 DB: ""
292ab48 0.041 1734 SQL: insert into test values(5,'TEST5')
292ab48 0.043 1734 CURSORFROM: 290e5c0 DB: ""
292ab48 0.044 1734 SQL: insert into test values(6,'TEST6')
290e5c0 0.046 1734 SQL: RELEASE SAVEPOINT "_apsw-1"
290e5c0 0.047 1734 SQL: RELEASE SAVEPOINT "_apsw-0"
292acd0 0.049 1734 CURSORFROM: 290e5c0 DB: ""
292acd0 0.050 1734 SQL: select * from test
292acd0 0.052 1734 ROW: (1, "TEST1")
1 TEST1
292acd0 0.056 1734 ROW: (2, "TEST2")
2 TEST2
292acd0 0.059 1734 ROW: (3, "TEST3")
3 TEST3
292acd0 0.062 1734 ROW: (5, "TEST5")
5 TEST5
292acd0 0.066 1734 ROW: (6, "TEST6")
6 TEST6
APSW TRACE SUMMARY REPORT

Program run time                    0.072 seconds
Total connections                   1
Total cursors                       9
Number of threads used for queries  1
Total queries                       18
Number of distinct queries          14
Number of rows returned             5
Time spent processing queries       0.017 seconds

MOST POPULAR QUERIES

  3 SAVEPOINT "_apsw-1"
  3 RELEASE SAVEPOINT "_apsw-1"
  1 select * from test
  1 insert into test values(6,'TEST6')
  1 insert into test values(5,'TEST5')
  1 insert into test values(4,'TEST4')
  1 insert into test values(4,'Error')
  1 insert into test values(3,'TEST3')
  1 insert into test values(2,'TEST2')
  1 insert into test values(1,'TEST1')
  1 create table test(x primary key,y)
  1 SAVEPOINT "_apsw-0"
  1 ROLLBACK TO SAVEPOINT "_apsw-1"
  1 RELEASE SAVEPOINT "_apsw-0"

LONGEST RUNNING - AGGREGATE

  1  0.017 select * from test
  3  0.000 SAVEPOINT "_apsw-1"
  3  0.000 RELEASE SAVEPOINT "_apsw-1"
  1  0.000 insert into test values(6,'TEST6')
  1  0.000 insert into test values(5,'TEST5')
  1  0.000 insert into test values(4,'TEST4')
  1  0.000 insert into test values(4,'Error')
  1  0.000 insert into test values(3,'TEST3')
  1  0.000 insert into test values(2,'TEST2')
  1  0.000 insert into test values(1,'TEST1')
  1  0.000 create table test(x primary key,y)
  1  0.000 SAVEPOINT "_apsw-0"
  1  0.000 ROLLBACK TO SAVEPOINT "_apsw-1"
  1  0.000 RELEASE SAVEPOINT "_apsw-0"

LONGEST RUNNING - INDIVIDUAL

 0.017 select * from test
 0.000 insert into test values(6,'TEST6')
 0.000 insert into test values(5,'TEST5')
 0.000 insert into test values(4,'TEST4')
 0.000 insert into test values(4,'Error')
 0.000 insert into test values(3,'TEST3')
 0.000 insert into test values(2,'TEST2')
 0.000 insert into test values(1,'TEST1')
 0.000 create table test(x primary key,y)
 0.000 SAVEPOINT "_apsw-1"
 0.000 SAVEPOINT "_apsw-1"
 0.000 SAVEPOINT "_apsw-1"
 0.000 SAVEPOINT "_apsw-0"
 0.000 ROLLBACK TO SAVEPOINT "_apsw-1"
 0.000 RELEASE SAVEPOINT "_apsw-1"

C:\dev\python\apsw>

Weitere Einzelheiten entnehmen Sie bitte dem Folgenden. http://rogerbinns.github.io/apsw/execution.html#apswtrace

APSW ist schneller als Pysqlite

Die folgenden Tests zeigen, dass APSW schneller als Pysqlite ist. http://rogerbinns.github.io/apsw/benchmarking.html

Referenz

APSW 3.8.7.3-r1 documentation » pysqlite differences http://rogerbinns.github.io/apsw/pysqlite.html#pysqlitediffs

Recommended Posts

Versuchen Sie es mit APSW, einer Python-Bibliothek, die SQLite ernst nehmen kann
Aus einem Buch, das Programmierer lernen können ... (Python): Über das Sortieren
Versuchen Sie, ein neuronales Netzwerk in Python aufzubauen, ohne eine Bibliothek zu verwenden
Ein Hinweis zu Mock (Python-Mock-Bibliothek)
Erstellt eine Bibliothek für Python, die die morphologische Teilung problemlos handhaben kann
Versuchen Sie es mit virtualenv, mit dem eine virtuelle Umgebung von Python erstellt werden kann
Versuchen Sie HTML-Scraping mit der Python-Bibliothek
Ein Programm, das Python zum Abspielen von Junk verwendet
Versuchen Sie es mit Platypus, einer Mehrzweckoptimierungsbibliothek
Erstellt Simple SQLite, eine Python-Bibliothek, die das Erstellen / Einfügen von SQLite-Tabellen vereinfacht
Versuchen Sie, mithilfe der Python-Anforderungsbibliothek eine Webseite und eine JSON-Datei abzurufen
Ich habe PyQCheck, eine Bibliothek, die QuickCheck mit Python ausführen kann, in PyPI registriert.
Ich habe versucht, die Python-Bibliothek "pykakasi" zu verwenden, die Kanji in Romaji konvertieren kann.
So installieren Sie die Python-Bibliothek, die von Pharmaunternehmen verwendet werden kann
Ein Memorandum über die Python-Tesseract-Wrapper-Bibliothek
Ein Hinweis zur Bibliotheksimplementierung, in der Hyperparameter mithilfe der Bayes'schen Optimierung in Python untersucht werden
Eine Geschichte über einen Python-Anfänger, der versucht, Google-Suchergebnisse mithilfe der API abzurufen
(Python) Versuchen Sie, eine Webanwendung mit Django zu entwickeln
Aus einem Buch, das Programmierer lernen können ... (Python): Zeiger
Erstellt eine Python-Bibliothek DateTimeRange, die Zeitbereiche verarbeitet
[Python] Eine praktische Bibliothek, die Kanji in Hiragana konvertiert
Versuchen Sie es mit Tweepy [Python2.7]
Veröffentlichung einer Bibliothek, die Zeichendaten in Python-Bildern verbirgt
[Python] Kapitel 01-03 Über Python (Schreiben und Ausführen eines Programms mit PyCharm)
Probieren Sie die ähnliche Suche von Image Search mit Python SDK [Search] aus.
Aus einem Buch, das Programmierer lernen können (Python): Nachrichten dekodieren
Entwickelte eine Bibliothek, um die Kindle-Sammlungsliste in Python abzurufen
Skripte, die bei der Verwendung von Bottle in Python verwendet werden können
Versuchen Sie, eine in Python geschriebene Funktion mit Fn Project auszuführen
Probieren Sie Juniper JUNOS PyEz (Python-Bibliothek) aus. Hinweis 2 ~ Informationen mit PyEz ~ abrufen ~
[Python] Versuchen Sie, Tkinters Leinwand zu verwenden
Memorandum über Korrelation [Python]
Ein Memorandum über den Python-Mock
Ein Hinweis zu [Python] __debug__
[Python] Erstellen Sie ein Diagramm, das mit Plotly verschoben werden kann
[Python] Ich habe meine eigene Bibliothek erstellt, die dynamisch importiert werden kann
Ich habe ein Paket erstellt, das morphologische Analysegeräte mit Python vergleichen kann
Verwenden Sie networkx, eine Bibliothek, die Diagramme in Python verarbeitet (Teil 2: Lernprogramm).
[Python] Ein Memo, das ich versucht habe, mit Asyncio zu beginnen
Aus einem Buch, das der Programmierer lernen kann ... (Python): Finden Sie den häufigsten Wert
Aus einem Buch, das Programmierer lernen können ... (Python): Überprüfung von Arrays
Ein bisschen mehr über Referenzen ~ Verwenden von Python und Java als Beispiele ~
Eine Geschichte über einen Erstellungsfehler in einer gemeinsam genutzten Bibliothek, die auf libusb verweist
[Ev3dev] Erstellen Sie ein Programm, das das LCD (Bildschirm) mit Python erfasst
Ich habe ein Shuffle gemacht, das mit Python zurückgesetzt (zurückgesetzt) werden kann
Bei Verwendung von @property in Python wird ein Attribut nicht festgelegt
Nachdem ich die Python-Bibliothek recherchiert hatte, verstand ich ein wenig über ei.info.
[Python] Ich habe eine Klasse erstellt, die schnell einen Dateibaum schreiben kann
Aus einem Buch, das Programmierer lernen können (Python): Statistischer Verarbeitungsabweichungswert