<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog::Quibb &#187; sqlite</title>
	<atom:link href="http://blog.quibb.org/tag/sqlite/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.quibb.org</link>
	<description>Software development and more.</description>
	<lastBuildDate>Tue, 10 Aug 2010 14:11:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Fast Bulk Inserts into SQLite</title>
		<link>http://blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/</link>
		<comments>http://blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 14:11:56 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://blog.quibb.org/?p=219</guid>
		<description><![CDATA[Background Sometimes it’s necessary to get information into a database quickly. SQLite is a light weight database engine that can be easily embedded in applications. This will cover the process of optimizing bulk inserts into an SQLite database. While this article focuses on SQLite some of the techniques shown here will apply to other databases. [...]]]></description>
			<content:encoded><![CDATA[<h2>Background</h2>
<p>Sometimes it’s necessary to get information into a database quickly. <a title="SQLite" href="http://sqlite.org/"> SQLite</a> is a light weight database engine that can be easily embedded in applications.  This will cover the process of optimizing bulk inserts into an SQLite database.  While this article focuses on SQLite some of the techniques shown here will apply to other databases.</p>
<p>All of the following examples insert data into the same table.  It&#8217;s a table where an ID is the first element followed by three FLOAT values, and then follow by three INTEGER values.  You&#8217;ll notice the getDouble() and getInt() functions.  They return doubles and ints in a predictable manner.  I didn&#8217;t use random data because different values could potentially add variability to the benchmarks at the end.</p>
<h2>Naive Inserts</h2>
<p>This is the most basic way to insert information into SQLite.  It simply calls <a title="sqlite3_exec" href="http://www.sqlite.org/c3ref/exec.html">sqlite3_exec</a> for each insert in the database.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">300</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> mVal<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">sprintf</span><span style="color: #008000;">&#40;</span>buffer, <span style="color: #FF0000;">&quot;INSERT INTO example VALUES ('%s', %lf, %lf, %lf, %d, %d, %d)&quot;</span>,
            getID<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,
            getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, buffer, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<h2>Inserts within a Transaction</h2>
<p>A transaction is a way to group SQL statements together.  If an error is encountered the ON CONFLICT statement can be used to handle that to your liking.  Nothing will be written to the SQLite database until either END or COMMIT is encountered to signify the transaction should be closed and written.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> errorMessage<span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;BEGIN TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">300</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> mVal<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">sprintf</span><span style="color: #008000;">&#40;</span>buffer, <span style="color: #FF0000;">&quot;INSERT INTO example VALUES ('%s', %lf, %lf, %lf, %d, %d, %d)&quot;</span>,
            getID<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>,
            getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, buffer, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;COMMIT TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<h2>PRAGMA Statements</h2>
<p><a title="PRAGMA" href="http://sqlite.org/pragma.html">PRAGMA</a> statements control the behavior of SQLite as a whole.  They can be used to tweak options such as how often the data is flushed to disk of the size of the cache.  These are some that are commonly used for performance.  The SQLite documentation fully explains what they do and the implications of using them.  For example, synchronous off will cause SQLite to not stop and wait for the data to get written to the hard drive.  In the event of a crash or power failure, it is more likely the database could be corrupted.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;PRAGMA synchronous=OFF&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;PRAGMA count_changes=OFF&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;PRAGMA journal_mode=MEMORY&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;PRAGMA temp_store=MEMORY&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<h2>Prepared Statements</h2>
<p><a title="Prepared Statements" href="http://sqlite.org/c3ref/prepare.html">Prepared statements</a> are the recommended way of sending queries to SQLite.   Rather than parsing the statement over and over again, the parser only needs to be run once on the statement.  According to the documentation, sqlite3_exec is a convenience function  that calls sqlite3_prepare_v2(), sqlite3_step(), and then  sqlite3_finalize().  In my opinion, the documentation should more explicitly say that prepared statements are the preferred query method.  sqlite3_exec() should only be used for one time use queries.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> errorMessage<span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;BEGIN TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;INSERT INTO example VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)&quot;</span><span style="color: #008080;">;</span>
sqlite3_stmt<span style="color: #000040;">*</span> stmt<span style="color: #008080;">;</span>
sqlite3_prepare_v2<span style="color: #008000;">&#40;</span>mDb, buffer, <span style="color: #0000dd;">strlen</span><span style="color: #008000;">&#40;</span>buffer<span style="color: #008000;">&#41;</span>, <span style="color: #000040;">&amp;</span>stmt, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> mVal<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> id <span style="color: #000080;">=</span> getID<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_text<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">1</span>, id.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, id.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, SQLITE_STATIC<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_double<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">2</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_double<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">3</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_double<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">4</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">5</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">6</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">7</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>sqlite3_step<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span> <span style="color: #000040;">!</span><span style="color: #000080;">=</span> SQLITE_DONE<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Commit Failed!<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    sqlite3_reset<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;COMMIT TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_finalize<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<h2>Storing Data as Binary Blob</h2>
<p>Up until now, most of the optimizations have been pretty much the standard advice that you get when looking into bulk insert optimization.  If you’re not running queries on some of the data, it’s possible to convert it to binary and store it as a blob.  While it’s not advised to just throw everything into a blob and put it in the database, putting data that would be pulled and used together into a binary blob can make sense in some situations.</p>
<p>For example, if you have a point class (x, y, z) with REAL values, it might make sense to store them in a blob rather than three separate fields in row.  That’s only if you don’t need to make queries on the data though.  The benefit of this technique increases as more fields are converted into larger blobs.</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> errorMessage<span style="color: #008080;">;</span>
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;BEGIN TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;INSERT INTO example VALUES (?1, ?2, ?3, ?4, ?5)&quot;</span><span style="color: #008080;">;</span>
sqlite3_stmt<span style="color: #000040;">*</span> stmt<span style="color: #008080;">;</span>
sqlite3_prepare_v2<span style="color: #008000;">&#40;</span>mDb, buffer, <span style="color: #0000dd;">strlen</span><span style="color: #008000;">&#40;</span>buffer<span style="color: #008000;">&#41;</span>, <span style="color: #000040;">&amp;</span>stmt, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">unsigned</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> mVal<span style="color: #008080;">;</span> i<span style="color: #000040;">++</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    std<span style="color: #008080;">::</span><span style="color: #007788;">string</span> id <span style="color: #000080;">=</span> getID<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_text<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">1</span>, id.<span style="color: #007788;">c_str</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, id.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, SQLITE_STATIC<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">char</span> dblBuffer<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">24</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">double</span> d<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #008000;">&#123;</span>getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, getDouble<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">memcpy</span><span style="color: #008000;">&#40;</span>dblBuffer, <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span><span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span><span style="color: #000040;">&amp;</span>d, <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>d<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_blob<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">2</span>, dblBuffer, <span style="color: #0000dd;">24</span>, SQLITE_STATIC<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">3</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">4</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    sqlite3_bind_int<span style="color: #008000;">&#40;</span>stmt, <span style="color: #0000dd;">5</span>, getInt<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">int</span> retVal <span style="color: #000080;">=</span> sqlite3_step<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>retVal <span style="color: #000040;">!</span><span style="color: #000080;">=</span> SQLITE_DONE<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Commit Failed! %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, retVal<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
&nbsp;
    sqlite3_reset<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
sqlite3_exec<span style="color: #008000;">&#40;</span>mDb, <span style="color: #FF0000;">&quot;COMMIT TRANSACTION&quot;</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #0000ff;">NULL</span>, <span style="color: #000040;">&amp;</span>errorMessage<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
sqlite3_finalize<span style="color: #008000;">&#40;</span>stmt<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></div></div>

<p>Note: I just used memcpy here, but this would have issues going between big and little endian systems.  If that’s necessary, it would be a good idea to serialize the data using a serialization library (ie &#8211; <a title="protocol buffers" href="http://code.google.com/apis/protocolbuffers/docs/overview.html">protocol buffers</a> or <a title="MsgPack" href="http://msgpack.org/">msgpack</a>).</p>
<h2>Performance</h2>
<p>I ran benchmarks to test the performance of each method of inserting data.  Take note that the x axis does not scale linearly, it most closely matches a logarithmic scale.  The inserts per second graph was obtained by taking the number of inserts and dividing it by the total runtime.</p>
<div id="attachment_238" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/bulk_insert_runtime.png"><img class="size-medium wp-image-238 " title="SQLite Bulk Insert Runtime" src="http://blog.quibb.org/wp-content/uploads/2010/07/bulk_insert_runtime-300x182.png" alt="SQLite Bulk Insert Runtime" width="300" height="182" /></a><p class="wp-caption-text">SQLite Build Insert Runtime in Seconds</p></div>
<p style="text-align: center;">
<div id="attachment_239" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/inserts_per_second.png"><img class="size-medium wp-image-239" title="Inserts Per Second" src="http://blog.quibb.org/wp-content/uploads/2010/07/inserts_per_second-300x182.png" alt="Inserts Per Second" width="300" height="182" /></a><p class="wp-caption-text">SQLite Inserts Per Second</p></div>
<p style="text-align: center;"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/inserts_per_second.png"></a></p>
<p style="text-align: left;">After running the first benchmark, I wanted to show how storing data in binary can make a difference.  I ran it again, but instead of storing only three doubles, I stored 24 doubles.  I assumed order mattered, so for the benchmark that is not stored in a binary blob, I made a separate table with ID and order columns.  This way both versions captured the same information.</p>
<p style="text-align: left;">
<div id="attachment_242" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/big_insert_runtime.png"><img class="size-medium wp-image-242" title="Big Insert Runtime" src="http://blog.quibb.org/wp-content/uploads/2010/07/big_insert_runtime-300x182.png" alt="Big Insert Runtime" width="300" height="182" /></a><p class="wp-caption-text">Big Insert Runtime in Seconds</p></div>
<div id="attachment_244" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.quibb.org/wp-content/uploads/2010/07/big_insert_per_second.png"><img class="size-medium wp-image-244" title="Big Inserts Per Second" src="http://blog.quibb.org/wp-content/uploads/2010/07/big_insert_per_second-300x181.png" alt="Big Inserts Per Second" width="300" height="181" /></a><p class="wp-caption-text">Big Inserts Per Second</p></div>
<p>Good luck with your database inserts.</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;">
<h1 id="internal-source-marker_0.4793873936321398"><span style="font-size: 24pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Fast Bulk Inserts into SQLite</span></h1>
<h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Background</span></h2>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Sometimes it’s necessary to get information into a database quickly.  SQLite[</span><a href="http://sqlite.org/"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">http://sqlite.org/</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">]  is a light weight database engine that can be easily embedded in  applications.  This will cover the process of optimizing bulk inserts  into an SQLite database.  While this article focuses on SQLite some of  the techniques shown here will apply to other databases.</span></p>
<h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Naive Inserts</span></h2>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">This is the most basic way to insert information into SQLite.  It simply calls sqlite3_exec[</span><a href="http://www.sqlite.org/c3ref/exec.html"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">http://www.sqlite.org/c3ref/exec.html</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">] for each insert in the database.</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert code here]</span></p>
<p><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Inserts within a Transaction</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">A  transaction is a way to group SQL statements together.  If an error is  encountered the ON CONFLICT statement can be used to handle that to your  liking.  Nothing will be written to the SQLite database until either  END or COMMIT is encountered to signify the transaction should be  written and closed.</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert code here]</span></p>
<h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">PRAGMA Statements</span></h2>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">PRAGMA statements[</span><a href="http://sqlite.org/pragma.html"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">http://sqlite.org/pragma.html</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">]  control the behavior of SQLite as a whole.  They can be used to tweak  options such as how often the data is flushed to disk of the size of the  cache.</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert code here]</span></p>
<h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Prepared Statements</span></h2>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Prepared statements[</span><a href="http://sqlite.org/c3ref/prepare.html"><span style="font-size: 11pt; font-family: Arial; color: #000099; background-color: transparent; font-weight: normal; font-style: normal; vertical-align: baseline; text-decoration: underline;">http://sqlite.org/c3ref/prepare.html</span></a><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">]  are the recommended way of sending queries to SQLite.  Rather than  parsing the statement over and over again, the parser only needs to be  run once on the statement.  In all honesty, the documentation for  sqlite3_exec should say not to use it at all in favor of prepared  statements.  They are not only faster on inserts, but across the board  for all SQL statements.</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert cod here]</span></p>
<h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Storing Data as Binary Blob</span></h2>
<p><span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Up  until now, most of the optimizations have been pretty much the standard  advice that you get when looking into bulk insert optimization.  If  you’re not running queries on some of the data, it’s possible to convert  it to binary and store it as a blob.  While it’s not advised to just  throw everything into a blob and put it in the database, putting data  that would be pulled and used together into a binary blob can make sense  in some situations.</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">For  example, if you have a point class (x, y, z) with REAL values, it might  make sense to store them in a blob rather than three separate fields in  row.  That’s only if you don’t need to make queries on the data though.   The benefits of this technique increase as more fields are converted  into larger blobs.</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">[insert code here]</span><br />
<span style="font-size: 11pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline;">Note:  I just do a memcpy here, but this would have issues going between big  and little endian systems.  If that’s necessary, it would be a good idea  to serialize the data using a serialization library (ie &#8211; protocol  buffers[http://code.google.com/apis/protocolbuffers/docs/overview.html],  msgpack[http://msgpack.org/],  thrift[http://incubator.apache.org/thrift/]).</span></p>
<h2><span style="font-size: 18pt; font-family: Arial; color: #000000; background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline;">Performance</span></h2>
<p>Fast Bulk Inserts into SQLite</p>
<p>Background</p>
<p>Sometimes it’s necessary to get information into a database quickly.  SQLite[http://sqlite.org/] is a light weight database engine that can be easily embedded in applications.  This will cover the process of optimizing bulk inserts into an SQLite database.  While this article focuses on SQLite some of the techniques shown here will apply to other databases.</p>
<p>Naive Inserts</p>
<p>This is the most basic way to insert information into SQLite.  It simply calls sqlite3_exec[http://www.sqlite.org/c3ref/exec.html] for each insert in the database.</p>
<p>[insert code here]</p>
<p>Inserts within a Transaction</p>
<p>A transaction is a way to group SQL statements together.  If an error is encountered the ON CONFLICT statement can be used to handle that to your liking.  Nothing will be written to the SQLite database until either END or COMMIT is encountered to signify the transaction should be written and closed.</p>
<p>[insert code here]</p>
<p>PRAGMA Statements</p>
<p>PRAGMA statements[http://sqlite.org/pragma.html] control the behavior of SQLite as a whole.  They can be used to tweak options such as how often the data is flushed to disk of the size of the cache.</p>
<p>[insert code here]</p>
<p>Prepared Statements</p>
<p>Prepared statements[http://sqlite.org/c3ref/prepare.html] are the recommended way of sending queries to SQLite.  Rather than parsing the statement over and over again, the parser only needs to be run once on the statement.  In all honesty, the documentation for sqlite3_exec should say not to use it at all in favor of prepared statements.  They are not only faster on inserts, but across the board for all SQL statements.</p>
<p>[insert cod here]</p>
<p>Storing Data as Binary Blob</p>
<p>Up until now, most of the optimizations have been pretty much the standard advice that you get when looking into bulk insert optimization.  If you’re not running queries on some of the data, it’s possible to convert it to binary and store it as a blob.  While it’s not advised to just throw everything into a blob and put it in the database, putting data that would be pulled and used together into a binary blob can make sense in some situations.</p>
<p>For example, if you have a point class (x, y, z) with REAL values, it might make sense to store them in a blob rather than three separate fields in row.  That’s only if you don’t need to make queries on the data though.  The benefits of this technique increase as more fields are converted into larger blobs.</p>
<p>[insert code here]</p>
<p>Note: I just do a memcpy here, but this would have issues going between big and little endian systems.  If that’s necessary, it would be a good idea to serialize the data using a serialization library (ie &#8211; protocol buffers[http://code.google.com/apis/protocolbuffers/docs/overview.html], msgpack[http://msgpack.org/], thrift[http://incubator.apache.org/thrift/]).</p>
<p>Performance</p>
</div>
<p><span id="more-219"></span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.quibb.org/2010/08/fast-bulk-inserts-into-sqlite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting Python, Elixir, and SQLite</title>
		<link>http://blog.quibb.org/2009/05/starting-python-elixir-and-sqlite/</link>
		<comments>http://blog.quibb.org/2009/05/starting-python-elixir-and-sqlite/#comments</comments>
		<pubDate>Mon, 18 May 2009 22:41:09 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[elixir]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://blog.quibb.org/?p=59</guid>
		<description><![CDATA[When I did the post about Storm, someone suggested that I look into Elixir. Since I didn&#8217;t have time to at the time, I made a note of looking into it at a later time.  That time is now. :) Elixir and Storm are very similar, they&#8217;re both object relational mappers that provide an easy [...]]]></description>
			<content:encoded><![CDATA[<p>When I did the <a href="http://blog.quibb.org/2009/03/the-ease-of-python-sqlite-and-storm/">post</a> about <a href="https://storm.canonical.com/">Storm</a>, someone suggested that I look into Elixir.  Since I didn&#8217;t have time to at the time, I made a note of looking into it at a later time.  That time is now. :)</p>
<p><a href="http://elixir.ematia.de/trac/wiki">Elixir</a> and <a href="https://storm.canonical.com/">Storm</a> are very similar, they&#8217;re both object relational mappers that provide an easy way to map your objects to database tables.  In a future post, I&#8217;ll do a more in depth comparison between the two in a future post.</p>
<p>Starting out, Elixir uses <a href="http://www.sqlalchemy.org/">SQL Alchemy</a> as a backend.  While working with the tool you will probably find yourself running into things you may not understand if you&#8217;re not familiar with SQL Alchemy.  Keeping open a tab in firefox pointed at the SQL Alchemy documentation can be useful.  It does show through in certain instances.</p>
<p>There are two main starting points for an ORM tool.  There is the case where you&#8217;re starting with an existing database, and the case where you&#8217;re setting up the database from scratch.  Mapping to a table that already exists with Elixir can be a little tricky depending on the relationships.</p>
<p>It&#8217;s as simple as this to connect to a database:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">metadata.<span style="color: black;">bind</span> = <span style="color: #483d8b;">&quot;sqlite:///../sizedb.sqlite&quot;</span></pre></div></div>

<p>Here is a simple example:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Location<span style="color: black;">&#40;</span>Entity<span style="color: black;">&#41;</span>:
    using_options<span style="color: black;">&#40;</span>tablename=<span style="color: #483d8b;">'TABLE_LOC'</span><span style="color: black;">&#41;</span>
    loc_id = Field<span style="color: black;">&#40;</span>Integer, primary_key=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    location = Field<span style="color: black;">&#40;</span>UnicodeText<span style="color: black;">&#41;</span></pre></div></div>

<p>And here is a more complex example of connecting to an existing database table:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Comparison<span style="color: black;">&#40;</span>Entity<span style="color: black;">&#41;</span>:
    using_options<span style="color: black;">&#40;</span>tablename=<span style="color: #483d8b;">'TABLE_COMP'</span><span style="color: black;">&#41;</span>
    comp_id = Field<span style="color: black;">&#40;</span>Integer, primary_key=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    date_added = Field<span style="color: black;">&#40;</span>DateTime, default=<span style="color: #dc143c;">datetime</span>.<span style="color: #dc143c;">datetime</span>.<span style="color: black;">now</span><span style="color: black;">&#41;</span>
    hits = Field<span style="color: black;">&#40;</span>Integer, default=<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
    smaller = ManyToOne<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Phrase'</span>, colname=<span style="color: #483d8b;">'smaller_id'</span><span style="color: black;">&#41;</span>
    larger = ManyToOne<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Phrase'</span>, colname=<span style="color: #483d8b;">'larger_id'</span><span style="color: black;">&#41;</span>
    sentences = ManyToMany<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Sentence'</span>, tablename=<span style="color: #483d8b;">'TABLE_COMP_SENT'</span>,
                           local_side=<span style="color: #483d8b;">'comp_id'</span>, remote_side=<span style="color: #483d8b;">'sent_id'</span>, column_format=<span style="color: #483d8b;">&quot;%(key)s&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>I left out most of the class specific code to focus on Elixir.  One thing that took a while to figure out was how to setup a ManyToMany relationship with specific columns in my database.  The <em>column_format</em> parameter is the key to being able to specify your column names directly.  I really didn&#8217;t have to use any other options besides what you see above when connecting to an existing database.  Overall, I had about five database tables to connect.</p>
<p>Now if it was not being setup with an existing database, many of the parameters in the different relationships are unnecessary.  For comparison here is the same example if Elixir is used to create the database tables:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Comparison<span style="color: black;">&#40;</span>Entity<span style="color: black;">&#41;</span>:
    comp_id = Field<span style="color: black;">&#40;</span>Integer, primary_key=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    date_added = Field<span style="color: black;">&#40;</span>DateTime, default=<span style="color: #dc143c;">datetime</span>.<span style="color: #dc143c;">datetime</span>.<span style="color: black;">now</span><span style="color: black;">&#41;</span>
    hits = Field<span style="color: black;">&#40;</span>Integer, default=<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>
&nbsp;
    smaller = ManyToOne<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Phrase'</span><span style="color: black;">&#41;</span>
    larger = ManyToOne<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Phrase'</span><span style="color: black;">&#41;</span>
    sentences = ManyToMany<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Sentence'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>As you can see, it gets quite a bit simpler.  The underlying table information is no longer needed.  It created tables that were very similar to my hand-created tables that I had used with Storm.  When it comes to queries on the database, SQL Alchemist shows through.</p>
<p>I found the documentation on the Elixir webpage to be a little bit lacking in terms of queries.  SQL Alchemist has a <a href="http://www.sqlalchemy.org/docs/05/ormtutorial.html#querying">page</a> that more fully describes the query functions.  <strong>AND</strong> and <strong>OR</strong> operators are named <strong>and_ </strong>and <strong>or_</strong>, respectively, probably because <em>and</em> and <em>or</em> are reserved in Python.  I thought this was worth mentioning because they are common SQL operators.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.quibb.org/2009/05/starting-python-elixir-and-sqlite/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The ease of Python, SQLite, and Storm</title>
		<link>http://blog.quibb.org/2009/03/the-ease-of-python-sqlite-and-storm/</link>
		<comments>http://blog.quibb.org/2009/03/the-ease-of-python-sqlite-and-storm/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 00:43:21 +0000</pubDate>
		<dc:creator>Joe</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[sqlite]]></category>
		<category><![CDATA[storm]]></category>

		<guid isPermaLink="false">http://blog.quibb.org/?p=31</guid>
		<description><![CDATA[I began learning Python this spring, and I must say, the more I program in it the more I like it. I chose the language because of the libraries that are available for it. There is a library for everything. :) Also, there are tools for Natural Language Processing that are a great help, but [...]]]></description>
			<content:encoded><![CDATA[<p>I began learning Python this spring, and I must say, the more I program in it the more I like it.  I chose the language because of the libraries that are available for it.  There is a library for everything. :)  Also, there are <a href="http://www.nltk.org">tools</a> for Natural Language Processing that are a great help, but that&#8217;s for another time and another post.</p>
<p>I was originally thinking about using Postgres, and it would probably give me better speed and scalability. But then, I began to think if I really needed a full RDBMS for my application.  After all, I&#8217;m not expecting the project to get too large, and being able to easily move it from one computer to another by just moving a single files sounds very convenient.  SQLite has a <a href="http://www.sqlite.org/whentouse.html">great page</a> to see if it&#8217;s right for you. I ended up settling on SQLite, and so far am happy with the decision.</p>
<p>Installing SQLite was a breeze.  I just opened the package manager in openSuSE and installed the packages.  I also installed the python Storm package.  There is no daemon process, as there is with Postgres, because you&#8217;re just accessing one file on your filesystem.  There is a great tool for setting up a SQLite database called <a href="http://code.google.com/p/sqlite-manager/">SQLite Manager</a>.  It will let you create tables, view your data, and run queries.  The fact that it&#8217;s available as a firefox extention makes it easy to install on many platforms.</p>
<p>Now is when the real fun begins. Enter <a href="https://storm.canonical.com/">Storm</a>.</p>
<p>Storm is an object relation mapping (ORM) tool for Python.  It allows you to manipulate the database through the manipulation of Python objects.  After you map your python objects to database tables, you manipulate them, and your changes will show up in the database for you.  I&#8217;ve used other ORM tools in the past (Hibernate for Java), but I was amazed at the simplicity of the setup/configuration step when using Storm.</p>
<p>It takes two lines to connect to your sqlite database:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">DATABASE = create_database<span style="color: black;">&#40;</span><span style="color: #483d8b;">'sqlite:db_name'</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># or simply create_database('sqlite:') for in-memory</span>
STORE = Store<span style="color: black;">&#40;</span>DATABASE<span style="color: black;">&#41;</span></pre></div></div>

<p>Mapping a class to a table can be done with ease.  Here is an example of one of my classes:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">class</span> Sentence<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:
    __storm_table__ = <span style="color: #483d8b;">&quot;TABLE_SENT&quot;</span>
    sent_id = Int<span style="color: black;">&#40;</span>primary=<span style="color: #008000;">True</span><span style="color: black;">&#41;</span>
    loc_id = Int<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
    location = Reference<span style="color: black;">&#40;</span>loc_id, Location.<span style="color: black;">loc_id</span><span style="color: black;">&#41;</span>
    sentence = Unicode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, sent, loc = <span style="color: #008000;">None</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">if</span> loc: <span style="color: #008000;">self</span>.<span style="color: black;">location</span> = loc
&nbsp;
        <span style="color: #808080; font-style: italic;"># sent cannot be None</span>
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>sent, <span style="color: #008000;">unicode</span><span style="color: black;">&#41;</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">sentence</span> = <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>sent, <span style="color: #483d8b;">&quot;utf-8&quot;</span><span style="color: black;">&#41;</span>
        <span style="color: #ff7700;font-weight:bold;">else</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">sentence</span> = sent</pre></div></div>

<p>If you access loc_id, it will give you the database id.  If you access the variable without location through a Reference, it will hand you the corresponding database object.</p>
<p>Now, I set this up in about 45 minutes from start to finish, so it might need some more fiddling, but overall it seems to work pretty well.  I needed to set something up in one night to keep moving on other parts of the project, and this allowed me to.</p>
<p>It can&#8217;t all be sunshine and rainbows, there was one thing that tripped me up a bit.  Being new to Python, I wasn&#8217;t aware of the u&#8221;String&#8221; for unicode.  It was used in their examples, and after I got an error assumed that&#8217;s what it was for, but it tripped me up.  As you can see in my constructor, I added some code to handle the case when a string that isn&#8217;t unicode is passed in.</p>
<p>As I get into the more advanced aspects of SQLite/Storm, I hope I continue to be impressed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.quibb.org/2009/03/the-ease-of-python-sqlite-and-storm/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
