<?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>Erics Tech Blog &#187; MySQL</title>
	<atom:link href="http://eric.lubow.org/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://eric.lubow.org</link>
	<description>Thoughts, musings, and other idealistic (sometimes useful) systems and development hoopla.</description>
	<lastBuildDate>Fri, 18 Nov 2011 14:56:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.4</generator>
		<item>
		<title>MySQL for Python</title>
		<link>http://eric.lubow.org/2010/book-reviews/mysql-for-python/</link>
		<comments>http://eric.lubow.org/2010/book-reviews/mysql-for-python/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 07:10:22 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Book Reviews]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=812</guid>
		<description><![CDATA[I am always for using the right tool for the right job. A lot of time, that tool is Python. I have always had trouble finding solid documentation on using MySQL with Python. There was generally enough to get by, but the more the merrier. Enter MySQL for Python by Albert Lukaszewski. As I mention [...]]]></description>
			<content:encoded><![CDATA[<p>I am always for using the right tool for the right job.  A lot of time, that tool is Python.  I have always had trouble finding solid documentation on using MySQL with Python.  There was generally enough to get by, but the more the merrier.  Enter MySQL for Python by Albert Lukaszewski. <span id="more-812"></span> <div id="attachment_813" class="wp-caption alignright" style="width: 110px"><a href="http://eric.lubow.org/wp-content/uploads/2010/12/mysql_for_python.jpg"><img src="http://eric.lubow.org/wp-content/uploads/2010/12/mysql_for_python.jpg" alt="MySQL for Python Cover" title="MySQL for Python Cover" width="100" height="129" class="size-full wp-image-813" /></a><p class="wp-caption-text">MySQL for Python</p></div></p>
<p>As I mention in most of my reviews, on the of the things I love about Packt Publishing books is that they typically follow the same pattern: installation, teaching, project, summary.  And my favorite piece is the mini projects given at the end of each chapter.  It&#8217;s a little reality check for the reader reminding them that everything that they are doing has a real life application.</p>
<p>So skipping the installation chapter and jumping right in to the teaching, there is a lot of discussion about how to do the common stuff that one does in MySQL through Python.  If you have a lot of experience with MySQL, then this is a handy reference.  I also really like the fact that scattered throughout the book is information on becoming a better programmer (like tradeoffs on memory efficiency vs. performance).</p>
<p>Chapter 4 contained information about exception handling.  Just like previous chapters, the amount of information on the handling of warnings and exceptions exceeds the boundaries of just MySQL in Python.  This was a great review for any Python programmer.  No need for further discussion as this chapter is available from Packt Publishing <a href="https://www.packtpub.com/sites/default/files/0189OS-Chapter-4-Exception-Handling.pdf">here</a>.</p>
<p>The next few chapters deal with data manipulation in Python.  This includes INSERTs, UPDATEs, DELETEs, etc.  Chapter 8 specifically deals with user management in MySQL.  This is a great skill to have regardless of the interface that you are using to tie into MySQL.  Most programmers neglect the concept of administration and leave it to the DBAs or the SysAdmins. Albert takes the reader through some admin exercises including user management, backup and recovery, and accessing the MySQL meta information like <em>information_schema</em> tables.  There was also discussion about the various storage engines which was unexpected.</p>
<p>Bouncing backwards a little was a lesson on the string and aggregation functions built into MySQL.  A lot of these capabilities are usually handled programatically and not off-loaded to the database like it should be.  Again, this is a great refresher (or even initial) lesson for any programmer who spends a lot of time building and maintaining complex queries.</p>
<p>Overall this book was another great teaching tool put forth by the folks at Packt.  The audience is definitely not at the beginner Python programmer, but an intermediate level developer would have no issues understanding everything.  You can find this book either at <a href="http://www.amazon.com/MySQL-Python-Albert-Lukaszewski/dp/1849510180">Amazon</a> or directly from <a href="https://www.packtpub.com/mysql-for-python-database-access-made-easy/book">Packt Publishing</a>.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/book-reviews/mod-security-2-5-by-magnus-mischel/' rel='bookmark' title='Mod-Security 2.5 by Magnus Mischel'>Mod-Security 2.5 by Magnus Mischel</a></li>
<li><a href='http://eric.lubow.org/2009/python/python-multiprocessing-pools-and-mysql/' rel='bookmark' title='Python Multiprocessing Pools and MySQL'>Python Multiprocessing Pools and MySQL</a></li>
<li><a href='http://eric.lubow.org/2007/book-reviews/building-telephony-systems-with-asterisk/' rel='bookmark' title='Building Telephony Systems With Asterisk'>Building Telephony Systems With Asterisk</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/book-reviews/mysql-for-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Database Read/Write Splitting in Frameworks/ORMs</title>
		<link>http://eric.lubow.org/2010/databases/mysql/database-readwrite-splitting-in-frameworksorms/</link>
		<comments>http://eric.lubow.org/2010/databases/mysql/database-readwrite-splitting-in-frameworksorms/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 13:00:27 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[frameworks]]></category>
		<category><![CDATA[scaling]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=563</guid>
		<description><![CDATA[Although one of the primary ideas behind frameworks is to keep things as simple as possible, sometimes they create issues in the long run. What I am about to discuss is something of a luxury problem (as scaling usually is), but it is a problem nonetheless. When initially starting a project, whether you are using [...]]]></description>
			<content:encoded><![CDATA[<p>Although one of the primary ideas behind frameworks is to keep things as simple as possible, sometimes they create issues in the long run.  What I am about to discuss is something of a luxury problem (as scaling usually is), but it is a problem nonetheless.</p>
<p>When initially starting a project, whether you are using <a href="http://rubyonrails.org/">Ruby on Rails</a> (Ruby), <a href="http://www.djangoproject.com/">Django</a> (Python), <a href="http://cakephp.org/">CakePHP</a> (PHP), <a href="http://www.catalystframework.org/">Catalyst</a> (Perl), or any of the other 100s of frameworks in any of the languages out there, the first and most important thing to do is to get it out the door.  Once you have done that, it&#8217;s time to get users, fix bugs, and add features.  After you have done all that and you have a great web app, its time to think scaling. (Yes I realize that I have trivialized this process immensely, but its for a point, I promise).<br />
<span id="more-563"></span><br />
When starting to scale (whether its out or up) and you decide its time to add another database, its necessary to analyze your app and decide whether its read heavy or write heavy.  A lot of scaling comes in knowing your application and where its bottlenecks are.  Let&#8217;s assume that you are at the point that you need to add a database server.  What would be great is if you had a framework that allowed you to set some database servers as read-only in order to take load off the master.</p>
<p>In an abstract format, it would be a good idea to break out your SQL requirements into 2 functions: <strong>sql_write_query</strong> and <strong>sql_read_query</strong>.  Then have the functions go to your primary database server and slave database servers respectively.  The reason that you should do this instead of using a single function that sends the query to the &#8220;correct&#8221; location based on the SQL it finds is that your slave servers may be behind the master (which is the nature of replication) which could give you an incorrect result in your query.  This way, depending on the importance and type of the query, in your code you can choose the location that you want to send the query to.  The read queries where accuracy is extremely important can be sent to the database using <strong>sql_write_query</strong> and all others can be executed normally using your <strong>sql_read_query</strong> function.</p>
<p>How does this relate to frameworks and ORMs?  It would be very handy if frameworks provided a method to expand an application into splitting read and write queries that is native to the frameworks.  If it is native and isn&#8217;t hacked on afterward (like below), then you don&#8217;t have to muck around in the core code or write a plugin and you can stick to what you know best (which is your application).  That is not to say that one should prematurely optimize an application (which is a whole other issue that you need to be careful of) and build it out in a split read/write fashion from the beginning, but that there should be a native way for the application to be faster should you reach that point.</p>
<p>Building this out as a afterthought can be done like what&#8217;s below (the example is in Python but can be extrapolated to the language specific to the framework).</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:450px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> MySQLdb<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> write_mysql_query<span style="color: black;">&#40;</span>query<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; conn <span style="color: #66cc66;">=</span> MySQLdb.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>host <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;dbvip1.example.com&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;root&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; passwd <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;pass&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;myapp&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor <span style="color: #66cc66;">=</span> conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SET AUTOCOMMIT=1&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>query<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> read_mysql_query<span style="color: black;">&#40;</span>query<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; conn <span style="color: #66cc66;">=</span> MySQLdb.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>host <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;slavedb1.example.com&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;root&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; passwd <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;pass&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; db <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;myapp&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor <span style="color: #66cc66;">=</span> conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>query<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; result <span style="color: #66cc66;">=</span> cursor.<span style="color: black;">fetchall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>You can even do things for the writer in a more transactional fashion using <em>START TRANSACTION</em> and <em>COMMIT</em> if you don&#8217;t like using <em>AUTOCOMMIT</em>.  You&#8217;ll also notice that there is a connect every time a query is executed.  A lot of people will have an initial gut reaction of a problem here.  In fact, since most of your queries will be taking place over a LAN with a pretty fast backplane (or some other variation of a high speed network), it&#8217;s probably negligible.  Taking the load off of your master and dispersing it onto slaves will make the most difference here.</p>
<p>All this is a very oversimplified way of taking this step, but it is something that frameworks should consider.  Even if its just in a plugin fashion which can be taken advantage of if the database server is getting overloaded.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/python/when-to-use-mysql-cursor-classes-in-python/' rel='bookmark' title='When To Use MySQL Cursor Classes In Python'>When To Use MySQL Cursor Classes In Python</a></li>
<li><a href='http://eric.lubow.org/2009/python/python-multiprocessing-pools-and-mysql/' rel='bookmark' title='Python Multiprocessing Pools and MySQL'>Python Multiprocessing Pools and MySQL</a></li>
<li><a href='http://eric.lubow.org/2009/python/pythons-mysqldb-2014-error-commands-out-of-sync/' rel='bookmark' title='Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync'>Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/databases/mysql/database-readwrite-splitting-in-frameworksorms/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>When To Use MySQL Cursor Classes In Python</title>
		<link>http://eric.lubow.org/2010/python/when-to-use-mysql-cursor-classes-in-python/</link>
		<comments>http://eric.lubow.org/2010/python/when-to-use-mysql-cursor-classes-in-python/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 15:00:40 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=526</guid>
		<description><![CDATA[I have been writing a lot of code that has been interacting with MySQL lately. Sometimes I find it easier to work the result set in a dictionary form and other times it is easier with an array. But in order to not break all your code, it is necessary to set a default cursor [...]]]></description>
			<content:encoded><![CDATA[<p>I have been writing a lot of code that has been interacting with MySQL lately.  Sometimes I find it easier to work the result set in a dictionary form and other times it is easier with an array.  But in order to not break all your code, it is necessary to set a default cursor class that keeps your code consistent.  More often than not, I find using using a arrays is easier since I just want quick access to all the retrieved data.  I also end up making my SELECT calls while specifying the columns and order of the columns I want returned.</p>
<p>The reason that using cursor classes is handy is because Python doesn&#8217;t come with a <strong>mysql_fetch_assoc</strong> like PHP or <strong>selectrow_hashref</strong> like Perl&#8217;s DBI interface.  Python uses cursor dictionaries to bridge this gap.  Ultimately your result is the same.  But as with Perl and PHP, defaulting to cursor dictionaries isn&#8217;t a good idea for larger datasets because of the extra processing time and memory required to convert the data.<br />
<span id="more-526"></span></p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> MySQLdb<br />
<br />
conn <span style="color: #66cc66;">=</span> MySQLdb.<span style="color: black;">Connect</span><span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; host<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'localhost'</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">'user'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; passwd<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'secret'</span><span style="color: #66cc66;">,</span> db<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'test'</span><span style="color: black;">&#41;</span><br />
cursor <span style="color: #66cc66;">=</span> conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SELECT this,that FROM foobar&quot;</span><span style="color: black;">&#41;</span><br />
rows <span style="color: #66cc66;">=</span> cursor.<span style="color: black;">fetchall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
cursor.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>This then allows me to do just call the DictCursor (dictionary based cursor) on a single cursor object for a particular query and leave all the rest of the queries as array based results.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> MySQLdb<br />
<span style="color: #ff7700;font-weight:bold;">import</span> MySQLdb.<span style="color: black;">cursors</span><br />
<br />
conn <span style="color: #66cc66;">=</span> MySQLdb.<span style="color: black;">Connect</span><span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; host<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'localhost'</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">'user'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; passwd<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'secret'</span><span style="color: #66cc66;">,</span> db<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'test'</span><span style="color: black;">&#41;</span><br />
cursor <span style="color: #66cc66;">=</span> conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span>cursorclass<span style="color: #66cc66;">=</span>MySQLdb.<span style="color: black;">cursors</span>.<span style="color: black;">DictCursor</span><span style="color: black;">&#41;</span><br />
cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SELECT this,that FROM foobar&quot;</span><span style="color: black;">&#41;</span><br />
rows <span style="color: #66cc66;">=</span> cursor.<span style="color: black;">fetchall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> row <span style="color: #ff7700;font-weight:bold;">in</span> rows:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">print</span> row<span style="color: black;">&#91;</span><span style="color: #483d8b;">'this'</span><span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> row<span style="color: black;">&#91;</span><span style="color: #483d8b;">'that'</span><span style="color: black;">&#93;</span><br />
cursor.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p><strong>Note:</strong> Doing something like changing the connection string to use a default cursor class of dictionary cursor in an existing code base is not a good idea.  It will make your results come back as dictionaries when your current code expects arrays.  Yes, I did this and had to track it down the hard way. Hopefully this saves you some trouble.</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">conn <span style="color: #66cc66;">=</span> MySQLdb.<span style="color: black;">Connect</span><span style="color: black;">&#40;</span><br />
&nbsp; &nbsp; host<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'localhost'</span><span style="color: #66cc66;">,</span> <span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span><span style="color: #483d8b;">'user'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; passwd<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'secret'</span><span style="color: #66cc66;">,</span> db<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'test'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; cursorclass<span style="color: #66cc66;">=</span>MySQLdb.<span style="color: black;">cursors</span>.<span style="color: black;">DictCursor</span><span style="color: black;">&#41;</span></div></div>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2009/python/python-multiprocessing-pools-and-mysql/' rel='bookmark' title='Python Multiprocessing Pools and MySQL'>Python Multiprocessing Pools and MySQL</a></li>
<li><a href='http://eric.lubow.org/2009/python/pythons-mysqldb-2014-error-commands-out-of-sync/' rel='bookmark' title='Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync'>Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync</a></li>
<li><a href='http://eric.lubow.org/2010/databases/mysql/database-readwrite-splitting-in-frameworksorms/' rel='bookmark' title='Database Read/Write Splitting in Frameworks/ORMs'>Database Read/Write Splitting in Frameworks/ORMs</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/python/when-to-use-mysql-cursor-classes-in-python/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MySQL Error 1033: Incorrect Information in File</title>
		<link>http://eric.lubow.org/2010/databases/mysql/mysql-error-1033-incorrect-information-in-file/</link>
		<comments>http://eric.lubow.org/2010/databases/mysql/mysql-error-1033-incorrect-information-in-file/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 14:15:43 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[errors]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=496</guid>
		<description><![CDATA[If you&#8217;ve ever been plagued by an error 1033 issue in MySQL (replication will show it as well), then I might be able to help you out. The error reads something like, &#8220;Incorrect information in file: &#8216;./mydb/table.frm&#8217;. I classify this as another one of MySQLs cryptic error messages. Here is how I determined that this [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever been plagued by an error 1033 issue in MySQL (replication will show it as well), then I might be able to help you out.  The error reads something like, &#8220;Incorrect information in file: &#8216;./mydb/table.frm&#8217;.  I classify this as another one of MySQLs cryptic error messages.  Here is how I determined that this was my problem.</p>
<p>Googling around got me an answer, but I had to read a bunch of different responses to piece together the answer. Essentially this issue (in my case) was a result of the InnoDB engine not loading up when MySQL was restarted.  Therefore when MySQL tried to read the frm file (table description) which was written for an InnoDB table with the MyISAM reader, it didn&#8217;t like it.  Since MyISAM is the fallback engine, it went to that and the table became unusable.<br />
<span id="more-496"></span></p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Last_Errno: 1033<br />
Last_Error: Error 'Incorrect information in file: './st/table.frm'' on query. Default database: 'mydb'. Query: 'INSERT INTO `table` (`id`,`col1`) VALUES (1,'foobar')'<br />
# or<br />
mysql&gt; REPAIR TABLE table;<br />
+-------------+--------+----------+----------------------------------------------------+<br />
| Table &nbsp; &nbsp; &nbsp; | Op &nbsp; &nbsp; | Msg_type | Msg_text &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |<br />
+-------------+--------+----------+----------------------------------------------------+<br />
| mydb.table &nbsp;| repair | Error &nbsp; &nbsp;| Incorrect information in file: './mydb/table.frm' &nbsp;| <br />
| mydb.table &nbsp;| repair | error &nbsp; &nbsp;| Corrupt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| <br />
+-------------+--------+----------+----------------------------------------------------+<br />
2 rows in set (0.02 sec)</div></div>
<p>I already knew my table <strong>table</strong> is an InnoDB table.  To be sure that this was the issue, I simply checked to see which engines were loaded (removed some for brevity).</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql&gt; SHOW ENGINES;<br />
+------------+----------+----------------------------------------------------------------+<br />
| Engine &nbsp; &nbsp; | Support &nbsp;| Comment &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br />
+------------+----------+----------------------------------------------------------------+<br />
| MyISAM &nbsp; &nbsp; | DEFAULT &nbsp;| Default engine as of MySQL 3.23 with great performance &nbsp; &nbsp; &nbsp; &nbsp; | <br />
| MEMORY &nbsp; &nbsp; | YES &nbsp; &nbsp; &nbsp;| Hash based, stored in memory, useful for temporary tables &nbsp; &nbsp; &nbsp;| <br />
| InnoDB &nbsp; &nbsp; | DISABLED | Supports transactions, row-level locking, and foreign keys &nbsp; &nbsp; | <br />
| CSV &nbsp; &nbsp; &nbsp; &nbsp;| YES &nbsp; &nbsp; &nbsp;| CSV storage engine &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <br />
+------------+----------+----------------------------------------------------------------+</div></div>
<p>So here I notice that InnoDB is disabled.  (Note: I skipped the step where I check my <strong>my.cnf</strong> to make sure the <em>skip-innodb</em> line in the <em>[mysqld]</em> section was commented out.  I already knew it was, but if you are unsure, check.)  So I pop over to the error log and I see this:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">InnoDB: Unable to lock ./ibdata1, error: 11<br />
InnoDB: Check that you do not already have another mysqld process<br />
InnoDB: using the same InnoDB data or log files.<br />
091222 15:21:55 &nbsp;InnoDB: Unable to open the first data file<br />
InnoDB: Error in opening ./ibdata1<br />
091222 15:21:55 &nbsp;InnoDB: Operating system error number 11 in a file operation.<br />
InnoDB: Error number 11 means 'Resource temporarily unavailable'.<br />
InnoDB: Some operating system error numbers are described at<br />
InnoDB: http://dev.mysql.com/doc/refman/5.0/en/operating-system-error-codes.html<br />
&nbsp;79InnoDB: Could not open or create data files.</div></div>
<p>This says to me that it is likely that the MySQL restart didn&#8217;t go as well as the initscript would have liked me to believe.  So I see what files are open and what&#8217;s running:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[root@db mysql]# lsof | grep ibdata1<br />
COMMAND &nbsp; &nbsp; PID &nbsp; &nbsp; &nbsp; &nbsp; USER &nbsp; FD &nbsp; &nbsp; &nbsp;TYPE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DEVICE &nbsp; &nbsp; &nbsp; &nbsp;SIZE &nbsp; &nbsp; &nbsp; NODE NAME<br />
mysqld &nbsp; &nbsp;24574 &nbsp; &nbsp; &nbsp; &nbsp;mysql &nbsp; &nbsp;4uW &nbsp; &nbsp; REG &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;8,3 &nbsp;5018484736 &nbsp; 61538308 /var/lib/mysql/ibdata1<br />
[root@db5 mysql]# ps ax | grep mysqld<br />
24536 pts/0 &nbsp; &nbsp;S &nbsp; &nbsp; &nbsp;0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql/ --pid-file=/var/lib/mysql//db.example.com.pid<br />
24574 pts/0 &nbsp; &nbsp;Sl &nbsp; &nbsp; 7:58 /usr/sbin/mysqld --basedir=/ --datadir=/var/lib/mysql/ --user=mysql --pid-file=/var/lib/mysql//db.example.com.pid --skip-external-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock<br />
26635 pts/0 &nbsp; &nbsp;S &nbsp; &nbsp; &nbsp;0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql/ --pid-file=/var/lib/mysql//db.example.com.pid<br />
26666 pts/0 &nbsp; &nbsp;Sl &nbsp; &nbsp; 0:06 /usr/sbin/mysqld --basedir=/ --datadir=/var/lib/mysql/ --user=mysql --pid-file=/var/lib/mysql//db.example.com.pid --skip-external-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock</div></div>
<p>Well look at that, 2 versions of MySQL running and <em>ibdata1</em> is being held open by one of them.  So now I do the ugly thing and kill the mysqld process that holding the file lock and then restart MySQL:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[root@db mysql]# kill -9 24574<br />
[root@db mysql]# ps ax | grep mysqld<br />
24536 pts/0 &nbsp; &nbsp;S &nbsp; &nbsp; &nbsp;0:00 /bin/sh /usr/bin/mysqld_safe --datadir=/var/lib/mysql/ --pid-file=/var/lib/mysql//db.example.com.pid<br />
27051 pts/0 &nbsp; &nbsp;Rl &nbsp; &nbsp; 0:02 /usr/sbin/mysqld --basedir=/ --datadir=/var/lib/mysql/ --user=mysql --pid-file=/var/lib/mysql//db.example.com.pid --skip-external-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock<br />
27075 pts/0 &nbsp; &nbsp;S+ &nbsp; &nbsp; 0:00 grep mysqld<br />
[root@db mysql]# /etc/init.d/mysql restart<br />
MySQL manager or server PID file could not be found! &nbsp; &nbsp; &nbsp; [FAILED]<br />
Starting MySQL............... &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[ &nbsp;OK &nbsp;]</div></div>
<p>So back over to MySQL:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">mysql&gt; SHOW ENGINES;<br />
+------------+----------+----------------------------------------------------------------+<br />
| Engine &nbsp; &nbsp; | Support &nbsp;| Comment &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br />
+------------+----------+----------------------------------------------------------------+<br />
| MyISAM &nbsp; &nbsp; | DEFAULT &nbsp;| Default engine as of MySQL 3.23 with great performance &nbsp; &nbsp; &nbsp; &nbsp; | <br />
| MEMORY &nbsp; &nbsp; | YES &nbsp; &nbsp; &nbsp;| Hash based, stored in memory, useful for temporary tables &nbsp; &nbsp; &nbsp;| <br />
| InnoDB &nbsp; &nbsp; | YES &nbsp; &nbsp; &nbsp;| Supports transactions, row-level locking, and foreign keys &nbsp; &nbsp; | <br />
| CSV &nbsp; &nbsp; &nbsp; &nbsp;| YES &nbsp; &nbsp; &nbsp;| CSV storage engine &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | <br />
+------------+----------+----------------------------------------------------------------+</div></div>
<p>There it is.  Now you should be able to start up replication again (if that was the issue).  Or if you didn&#8217;t discover this issue with replication, you should just be able to use your DB like normal.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2009/python/pythons-mysqldb-2014-error-commands-out-of-sync/' rel='bookmark' title='Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync'>Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync</a></li>
<li><a href='http://eric.lubow.org/2008/databases/mysql/mysql-encoded-uri-search-and-replace/' rel='bookmark' title='MySQL Encoded URI Search and Replace'>MySQL Encoded URI Search and Replace</a></li>
<li><a href='http://eric.lubow.org/2009/databases/mysql/counting-email-addresses-by-domain-in-mysql/' rel='bookmark' title='Counting Email Addresses By Domain in MySQL'>Counting Email Addresses By Domain in MySQL</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2010/databases/mysql/mysql-error-1033-incorrect-information-in-file/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Python Multiprocessing Pools and MySQL</title>
		<link>http://eric.lubow.org/2009/python/python-multiprocessing-pools-and-mysql/</link>
		<comments>http://eric.lubow.org/2009/python/python-multiprocessing-pools-and-mysql/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 12:00:00 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[multprocessing]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[pool]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=486</guid>
		<description><![CDATA[There really isn&#8217;t a solid Python module for multiprocessing and MySQL. Now this may be because MySQL on a single server is disk bound and therefore limited in speed or just because no one has written it. So here is a quick and dirty example using the Pool module in multiprocessing in Python 2.6 and [...]]]></description>
			<content:encoded><![CDATA[<p>There really isn&#8217;t a solid Python module for multiprocessing and MySQL.  Now this may be because MySQL on a single server is disk bound and therefore limited in speed or just because no one has written it.  So here is a quick and dirty example using the <strong>Pool</strong> module in <em>multiprocessing</em> in Python 2.6 and <a href="http://mysql-python.sourceforge.net/MySQLdb.html">MySQLdb</a>.</p>
<p>I also tried using <a href="http://code.google.com/p/pysqlpool/">PySQLPool</a>.  This was designed for threading and not forking as I am doing with Pool method.  Although I am sure it is possible to use PySQLPool with forking by passing the connection (pool) object down to the child process or possibly doing something with IPC, I decided to keep it simple (although slightly more expensive) and instantiate MySQLdb connections upon fork.<br />
<span id="more-486"></span></p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:450px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> MySQLdb<br />
<span style="color: #ff7700;font-weight:bold;">import</span> multiprocessing<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; tablename <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'address_demographics'</span><br />
&nbsp; &nbsp; inserts <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #008000;">id</span> <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">0</span> <br />
&nbsp; &nbsp; max_id <span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1000000</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">id</span> <span style="color: #66cc66;">&lt;</span> max_id:<br />
&nbsp; &nbsp; &nbsp; &nbsp; sql <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;&quot;&quot; <br />
&nbsp; &nbsp; &nbsp; &nbsp; INSERT IGNORE INTO `%s` (person_id)<br />
&nbsp; &nbsp; &nbsp; &nbsp; SELECT person_id<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM `people`<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WHERE id BETWEEN %d AND %d<br />
&nbsp; &nbsp; &nbsp; &nbsp; &quot;&quot;&quot;</span> % <span style="color: black;">&#40;</span>tablename<span style="color: #66cc66;">,</span><span style="color: #008000;">id</span><span style="color: #66cc66;">,</span><span style="color: black;">&#40;</span><span style="color: #008000;">id</span> + <span style="color: #ff4500;">100000</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; inserts.<span style="color: black;">append</span><span style="color: black;">&#40;</span>sql<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">id</span> +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">100001</span><br />
&nbsp; &nbsp; pool <span style="color: #66cc66;">=</span> multiprocessing.<span style="color: black;">Pool</span><span style="color: black;">&#40;</span>multiprocessing.<span style="color: black;">cpu_count</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; pool.<span style="color: #008000;">map</span><span style="color: black;">&#40;</span>sqlWorkerInsert<span style="color: #66cc66;">,</span> inserts<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; pool.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; pool.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> sqlWorkerInsert<span style="color: black;">&#40;</span>sql<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; conn <span style="color: #66cc66;">=</span> MySQLdb.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>host <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;127.0.0.1&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #dc143c;">user</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;USER&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;passwd <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;PASS&quot;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">&quot;DB&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor <span style="color: #66cc66;">=</span> conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Need to do this since AUTOCOMMIT = 0 by default (wtf?)</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SET AUTOCOMMIT=1&quot;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span>sql<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; cursor.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>It may not be the cleanest method to open a new connection to MySQL for every worker subprocess.  Since MySQL opens a new thread for every connection, I don&#8217;t think this is that big of a deal.  However I am always open to new ways of doing things.</code></p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/python/when-to-use-mysql-cursor-classes-in-python/' rel='bookmark' title='When To Use MySQL Cursor Classes In Python'>When To Use MySQL Cursor Classes In Python</a></li>
<li><a href='http://eric.lubow.org/2009/python/pythons-mysqldb-2014-error-commands-out-of-sync/' rel='bookmark' title='Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync'>Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync</a></li>
<li><a href='http://eric.lubow.org/2010/databases/mysql/database-readwrite-splitting-in-frameworksorms/' rel='bookmark' title='Database Read/Write Splitting in Frameworks/ORMs'>Database Read/Write Splitting in Frameworks/ORMs</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/python/python-multiprocessing-pools-and-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python&#8217;s MySQLdb 2014 Error &#8211; Commands out of sync</title>
		<link>http://eric.lubow.org/2009/python/pythons-mysqldb-2014-error-commands-out-of-sync/</link>
		<comments>http://eric.lubow.org/2009/python/pythons-mysqldb-2014-error-commands-out-of-sync/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 13:00:36 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[python]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=480</guid>
		<description><![CDATA[While writing a simple Python script to access and process data in a database, I came across an error that said: Error 2014: Commands out of sync; you can't run this command now After quite a bit of Googling and with very little findings, I had to dive in a little and try to figure [...]]]></description>
			<content:encoded><![CDATA[<p>While writing a simple Python script to access and process data in a database, I came across an error that said:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Error <span style="color: #ff4500;">2014</span>: Commands out of sync<span style="color: #66cc66;">;</span> you can<span style="color: #483d8b;">'t run this command now</span></div></div>
<p>After quite a bit of Googling and with very little findings, I had to dive in a little and try to figure out what was going on.  The whole error looked like this:<br />
<span id="more-480"></span></p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: black;">&#91;</span>elubow<span style="color: #66cc66;">@</span>web7 scripts<span style="color: black;">&#93;</span>$ ./<span style="color: #ff4500;">2014</span>_test.<span style="color: black;">py</span><br />
Traceback <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:<br />
&nbsp; File <span style="color: #483d8b;">&quot;build/bdist.linux-x86_64/egg/MySQLdb/cursors.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">173</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> execute<br />
&nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">errorhandler</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> exc<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span><br />
&nbsp; File <span style="color: #483d8b;">&quot;build/bdist.linux-x86_64/egg/MySQLdb/connections.py&quot;</span><span style="color: #66cc66;">,</span> line <span style="color: #ff4500;">36</span><span style="color: #66cc66;">,</span> <span style="color: #ff7700;font-weight:bold;">in</span> defaulterrorhandler<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">raise</span> errorclass<span style="color: #66cc66;">,</span> errorvalue<br />
ProgrammingError: <span style="color: black;">&#40;</span><span style="color: #ff4500;">2014</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">&quot;Commands out of sync; you can't run this command now&quot;</span><span style="color: black;">&#41;</span><br />
Error <span style="color: #ff4500;">2014</span>: Commands out of sync<span style="color: #66cc66;">;</span> you can<span style="color: #483d8b;">'t run this command now<br />
Exception _mysql_exceptions.ProgrammingError: (1064, &quot;You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '</span>test_table<span style="color: #483d8b;">' at line 1&quot;) in<br />
&lt;bound method Cursor.__del__ of &lt;MySQLdb.cursors.Cursor object at 0x2aac002f9d90&gt;&gt; ignored<br />
&lt;/bound&gt;</span></div></div>
<p>The issue turned out to be a very simple one to fix.  Apparently MySQLdb doesn&#8217;t support compound MySQL statements.  That is to say that this won&#8217;t work:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'SELECT COUNT(*) FROM people; SHOW TABLES LIKE addresses;'</span><span style="color: black;">&#41;</span></div></div>
<p>But this will work:</p>
<div class="codecolorer-container python default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SELECT COUNT(*) FROM people&quot;</span><span style="color: black;">&#41;</span><br />
cursor.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
cursor <span style="color: #66cc66;">=</span> conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SHOW TABLES LIKE addresses&quot;</span><span style="color: black;">&#41;</span></div></div>
<p>Make sure you break up your SQL statements into separate execute statements and you should avoid this MySQL 2014 error.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/python/when-to-use-mysql-cursor-classes-in-python/' rel='bookmark' title='When To Use MySQL Cursor Classes In Python'>When To Use MySQL Cursor Classes In Python</a></li>
<li><a href='http://eric.lubow.org/2009/python/python-multiprocessing-pools-and-mysql/' rel='bookmark' title='Python Multiprocessing Pools and MySQL'>Python Multiprocessing Pools and MySQL</a></li>
<li><a href='http://eric.lubow.org/2010/databases/mysql/mysql-error-1033-incorrect-information-in-file/' rel='bookmark' title='MySQL Error 1033: Incorrect Information in File'>MySQL Error 1033: Incorrect Information in File</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/python/pythons-mysqldb-2014-error-commands-out-of-sync/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Percona Conference Slides</title>
		<link>http://eric.lubow.org/2009/misc/percona-conference-slides/</link>
		<comments>http://eric.lubow.org/2009/misc/percona-conference-slides/#comments</comments>
		<pubDate>Sat, 09 May 2009 13:00:44 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Misc]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=162</guid>
		<description><![CDATA[For everyone who was not able to attend this year, here is the link to the Percona Perfmance Conference slides: http://conferences.percona.com/percona-performance-conference-2009/schedule.html. I suggest you check them out if you work with MySQL. Enjoy. Related posts:SysAdmin Of The Year Contest]]></description>
			<content:encoded><![CDATA[<p>For everyone who was not able to attend this year, here is the link to the Percona Perfmance Conference slides: <a href="http://conferences.percona.com/percona-performance-conference-2009/schedule.html">http://conferences.percona.com/percona-performance-conference-2009/schedule.html</a>.</p>
<p>I suggest you check them out if you work with MySQL.  Enjoy.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2009/misc/sysadmin-of-the-year-contest/' rel='bookmark' title='SysAdmin Of The Year Contest'>SysAdmin Of The Year Contest</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/misc/percona-conference-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Counting Email Addresses By Domain in MySQL</title>
		<link>http://eric.lubow.org/2009/databases/mysql/counting-email-addresses-by-domain-in-mysql/</link>
		<comments>http://eric.lubow.org/2009/databases/mysql/counting-email-addresses-by-domain-in-mysql/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 13:50:21 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[statistics]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=92</guid>
		<description><![CDATA[Every so often I find some statistical need that although Perl program would be easy to write for it, its probably something the database should just handle. So I have a column in an email management table that has just the email addresses in the format user@domain.tld. I want to know which domains make up [...]]]></description>
			<content:encoded><![CDATA[<p>Every so often I find some statistical need that although Perl program would be easy to write for it, its probably something the database should just handle.  So I have a column in an email management table that has just the email addresses in the format <strong>user@domain.tld</strong>.</p>
<p>I want to know which domains make up the majority of the users.  (The numbers have been changed to protect the innocent):</p>
<pre>
mysql> SELECT SUBSTRING_INDEX(email, '@', -1) as Domain, count(*) as Total
      FROM email_list
GROUP BY Domain
ORDER BY Total DESC
       LIMIT 15;
+----------------+---------+
| Domain         | Total   |
+----------------+---------+
| yahoo.com      | 1304000 |
| hotmail.com    |  908400 |
| aol.com        |  800000 |
| msn.com        |  168000 |
| gmail.com      |  161000 |
| comcast.net    |  143000 |
| sbcglobal.net  |  110000 |
| bellsouth.net  |   62000 |
| cox.net        |   58000 |
| verizon.net    |   56000 |
| earthlink.net  |   52000 |
| charter.net    |   46000 |
| juno.com       |   30000 |
| optonline.net  |   22000 |
| netzero.com    |   17000 |
+----------------+---------+
</pre>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2010/mail/list-of-feedback-loops/' rel='bookmark' title='List of Feedback Loops'>List of Feedback Loops</a></li>
<li><a href='http://eric.lubow.org/2009/mail/transferring-email-from-gmailgoogle-apps-to-dovecot-with-larch/' rel='bookmark' title='Transferring Email From Gmail/Google Apps to Dovecot With Larch'>Transferring Email From Gmail/Google Apps to Dovecot With Larch</a></li>
<li><a href='http://eric.lubow.org/2010/seo/seo-and-cross-domain-content-syndication/' rel='bookmark' title='SEO and Cross-Domain Content Syndication'>SEO and Cross-Domain Content Syndication</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2009/databases/mysql/counting-email-addresses-by-domain-in-mysql/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Character Encoding</title>
		<link>http://eric.lubow.org/2008/databases/mysql/character-encoding/</link>
		<comments>http://eric.lubow.org/2008/databases/mysql/character-encoding/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 21:44:58 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[character encoding]]></category>

		<guid isPermaLink="false">http://eric.lubow.org/?p=77</guid>
		<description><![CDATA[I recently ran into some character encoding issues and I wanted to share the fun. The default character encoding for MySQL on Gentoo is latin-1 or iso-8859-1. This wasn&#8217;t a problem until we recently started putting content straight from the DB through Java and onto the web. Java connects to the DB with a character [...]]]></description>
			<content:encoded><![CDATA[<p>I recently ran into some character encoding issues and I wanted to share the fun.  The default character encoding for MySQL on Gentoo is latin-1 or iso-8859-1.  This wasn&#8217;t a problem until we recently started putting content straight from the DB through Java and onto the web.  Java connects to the DB with a character encoding (typically UTF-8).  Since UTF-8 is roughly a superset of iso-8859-1, it generally wasn&#8217;t a problem.  Except when UTF-8 and UTF-16 characters were put into an iso-8859-1 database without translation.</p>
<p>What was essentially happening was that the data was being stored as iso-8859-1.  The Java code was connecting to the DB in UTF-8 and pulling it into Java (which is usually UTF-16, but in this case was being handled as UTF-8).  It was then being sent to the browser as URL encoded UTF-8 when in reality, it hadn&#8217;t even properly been put into UTF-8 character encoding.  This then gave the web browser some funny yen symbols and question marks.  This was not quite what we were aiming for.</p>
<p>The moral of this story is that it is necessary to realize the character encoding of the start point and end point of your data.  It is crucial that the code points match up otherwise they could potentially make for an interesting screen given to the reader.  All this could have been avoided with a simple: <strong>ALTER TABLE myTable MODIFY myColumn VARCHAR(255) CHARACTER SET utf8;</strong>.</p>


<p>Related posts:<ol><li><a href='http://eric.lubow.org/2008/databases/mysql/mysql-encoded-uri-search-and-replace/' rel='bookmark' title='MySQL Encoded URI Search and Replace'>MySQL Encoded URI Search and Replace</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://eric.lubow.org/2008/databases/mysql/character-encoding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

