<?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>Do Know Evil - A Blog by Tyler Mulligan &#187; MySQL</title> <atom:link href="http://www.doknowevil.net/category/computers/software/programming/mysql/feed/" rel="self" type="application/rss+xml" /><link>http://www.doknowevil.net</link> <description>Tips and Tricks About Computers, Web Development, Linux, the Internet and the Like</description> <lastBuildDate>Sat, 16 Jul 2011 01:25:35 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.0.5</generator> <item><title>MySQL and Python &#8211; The Problems and [Some] Solutions</title><link>http://www.doknowevil.net/2010/10/15/mysql-and-python-the-problems-and-some-solutions/</link> <comments>http://www.doknowevil.net/2010/10/15/mysql-and-python-the-problems-and-some-solutions/#comments</comments> <pubDate>Fri, 15 Oct 2010 22:22:59 +0000</pubDate> <dc:creator>Tyler Mulligan</dc:creator> <category><![CDATA[Computers]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[Python]]></category> <category><![CDATA[Software]]></category> <category><![CDATA[bugs]]></category> <category><![CDATA[caveats]]></category> <category><![CDATA[parameterization]]></category> <category><![CDATA[suggestions]]></category><guid isPermaLink="false">http://www.doknowevil.net/?p=826</guid> <description><![CDATA[Intro I&#8217;m still relatively new to Python. I dabble once in a while. Usually when I catch myself writing something overly complicated in bash. I figured doing MySQL from a Python script would be easier and better implemented in Python. Well, I was in for a few surprises I&#8217;d like to share with others looking]]></description> <content:encoded><![CDATA[<h2>Intro</h2><p>I&#8217;m still relatively new to Python.  I dabble once in a while.  Usually when I catch myself writing something overly complicated in bash.  I figured doing MySQL from a Python script would be easier and better implemented in Python.  Well, I was in for a few surprises I&#8217;d like to share with others looking to integrate with MySQL in Python before you encounter the same problems I did.</p><h2>Getting on with it</h2><p>As a Python noob, it made sense to me to use the python-mysqldb module.  It &#8220;works&#8221; but not well.  Read through the [working] code below and see if you can find the problem and how I circumvented it.</p><pre class="brush:python">#!/bin/python
# Tyler Mulligan (tyler@doknowevil.net)
# MySQL the WRONG way in Python
import MySQLdb

def connection_settings():
    global DB_ADMIN, DB_ADMIN_PASSWORD, DB_NAME, DB_HOST, DB_USER, DB_PASSWORD
    DB_ADMIN=&quot;root&quot;
    DB_ADMIN_PASSWORD=&quot;local&quot;
    DB_NAME=&quot;foobardb&quot;
    DB_HOST=&quot;localhost&quot;
    DB_USER=&quot;foobar&quot;
    DB_PASSWORD=&quot;local&quot;

def run_admin_sql():
    conn = MySQLdb.Connection(host=DB_HOST, user=DB_ADMIN, passwd=DB_ADMIN_PASSWORD)
    cursor = conn.cursor()

    #cursor.execute(&quot;DROP USER %s@%s&quot;, (DB_USER, DB_HOST))
    #cursor.execute(&quot;DROP DATABASE %s&quot; % DB_NAME)

    cursor.execute(&quot;CREATE USER %s@%s IDENTIFIED BY %s&quot;, (DB_USER, DB_HOST, DB_PASSWORD))
    cursor.execute(&quot;CREATE DATABASE %s&quot; % DB_NAME)
    cursor.execute(&quot;GRANT USAGE ON %s.* TO %s@%s IDENTIFIED BY &#039;%s&#039;&quot; % (DB_NAME, DB_USER, DB_HOST, DB_PASSWORD))
    cursor.execute(&quot;GRANT ALL PRIVILEGES ON *.* to %s@%s IDENTIFIED BY %s&quot;, (DB_USER, DB_HOST, DB_PASSWORD))

    cursor.close()
    conn.close()

    conn = MySQLdb.Connection(db=DB_NAME, host=DB_HOST, user=DB_USER, passwd=DB_PASSWORD)
    cursor = conn.cursor()

    cat_table_sql = &quot;&quot;&quot;CREATE TABLE cats
    (
    `id` int(3) unsigned NOT NULL AUTO_INCREMENT,
    `name` varchar(50) NOT NULL,
    `age` int(2) NOT NULL,
    `type` int(2) NOT NULL,
    PRIMARY KEY (`id`)
    )&quot;&quot;&quot;

    cursor.execute(cat_table_sql)
    cursor.execute(&quot;INSERT INTO cats (name, age, type) VALUES (%s, %s, %s)&quot;, (&quot;fluffy&quot;, 5, 1))
    cursor.execute(&quot;INSERT INTO cats (name, age, type) VALUES (%s, %s, %s)&quot;, (&quot;meow meow&quot;, 6, 1))
    cursor.execute(&quot;INSERT INTO cats (name, age, type) VALUES (%s, %s, %s)&quot;, (&quot;purrfect&quot;, 3, 1))

    cursor.execute(&quot;SELECT * FROM cats&quot;)

    results = cursor.fetchall()
    cursor.close()
    conn.close()
    return results

connection_settings()
print run_admin_sql()</pre><p>The problem is parameterization.  The python-mysqldb module sucks at it.  It&#8217;s glaringly obvious when you look at the follow snippet and how I worked around it.</p><pre class="brush:python">
cursor.execute(&quot;CREATE USER %s@%s IDENTIFIED BY %s&quot;, (DB_USER, DB_HOST, DB_PASSWORD)) # GOOD
cursor.execute(&quot;CREATE DATABASE %s&quot; % DB_NAME) # BAD NEWS BEARS
cursor.execute(&quot;CREATE DATABASE %s&quot;, (DB_NAME)) # but the module won&#039;t support this
</pre><p>The difference, is that the first implementation uses the module&#8217;s parameterization to escape the variables that are passed to it, making it safe.  The second is using Python&#8217;s string formatter which means I&#8217;d have to do all the escaping and sanitization prior, which is obviously more dangerous and annoying.</p><p>The MySQLdb docs bury this little note, &#8220;Parameter placeholders can only be used to insert column values. They can not be used for other parts of SQL, such as table names, statements, etc.&#8221;</p><p>You can implement it this way but you&#8217;ll be wasting your time.  There are better modules out there to make up for this one&#8217;s shortcomings. <a href="http://packages.python.org/oursql/" target="_blank">OurSQL</a> and <a href="http://www.sqlalchemy.org/" target="_blank">SQLAlchemy</a> were the two libraries recommended to me in #python on irc.freenode.org.  I will make another post when I develop the same example above using one of these libraries.</p> ]]></content:encoded> <wfw:commentRss>http://www.doknowevil.net/2010/10/15/mysql-and-python-the-problems-and-some-solutions/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Feather.php &#8211; Making form to database interactions easier</title><link>http://www.doknowevil.net/2008/01/31/featherphp-making-form-to-database-interactions-easier/</link> <comments>http://www.doknowevil.net/2008/01/31/featherphp-making-form-to-database-interactions-easier/#comments</comments> <pubDate>Thu, 31 Jan 2008 19:26:10 +0000</pubDate> <dc:creator>Tyler Mulligan</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://www.doknowevil.net/2008/01/31/featherphp-making-form-to-database-interactions-easier/</guid> <description><![CDATA[More often than not, when I&#8217;m doing form to database interactions, I use the same field names. This means there is some redundant information in my code, making my job more difficult. As such, I&#8217;ve started to create feather.php, a SQL statement constructor class that works off data sent by the $_POST or $_GET arrays.]]></description> <content:encoded><![CDATA[<p>More often than not, when I&#8217;m doing form to database interactions, I use the same field names.  This means there is some redundant information in my code, making my job more difficult.  As such, I&#8217;ve started to create <a href="http://www.doknowevil.net/scripts/feather/feather_example.php" title="Feather.php - Making form to database interactions easier - Tyler Mulligan" target="_blank">feather.php</a>, a SQL statement constructor class that works off data sent by the <b>$_POST</b> or <b>$_GET</b> arrays.</p><p><a href="http://www.doknowevil.net/scripts/feather/feather_example.php" title="Feather.php - Making form to database interactions easier - Tyler Mulligan" target="_blank"><img src="http://www.doknowevil.net/scripts/feather/images/feather_diagram.jpg" title="Feather.php Diagram - Created by Tyler Mulligan" /></a></p><p>It&#8217;s not ready for a public release as there are still some security issues to address (see <a href="http://www.doknowevil.net/scripts/feather/feather_example.php#fragment-6" title="Feather.php TODO List - PHP by Tyler Mulligan" target="_blank">TODO</a>) but I wanted to get some thoughts, opinions and suggestions on this.</p><p>For those of you concerned about using the same field names as database columns, I plan to add associative arrays to allow you use different names.</p><p>i.e. something like this:</p><pre class="brush:php">
$field_names array(&#039;the_first_name&#039;,&#039;the_last_name&#039;,&#039;the_zipcode&#039;);
$column_names = array(&#039;first_name&#039;,&#039;last_name&#039;,&#039;zipcode&#039;);
</pre>]]></content:encoded> <wfw:commentRss>http://www.doknowevil.net/2008/01/31/featherphp-making-form-to-database-interactions-easier/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Daily database backups on dreamhost</title><link>http://www.doknowevil.net/2007/12/13/daily-database-backups-on-dreamhost/</link> <comments>http://www.doknowevil.net/2007/12/13/daily-database-backups-on-dreamhost/#comments</comments> <pubDate>Thu, 13 Dec 2007 18:25:11 +0000</pubDate> <dc:creator>Tyler Mulligan</dc:creator> <category><![CDATA[Linux]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[dreamhost]]></category><guid isPermaLink="false">http://www.doknowevil.net/2007/12/13/daily-database-backups-on-dreamhost/</guid> <description><![CDATA[To do daily database backups, I use cron jobs. If you aren&#8217;t familiar with cron jobs, think of the as scripts that run on a timer. Much like &#8216;scheduled tasks&#8217; on windows. To edit your cron jobs on dreamhost, locate the &#8216;cron jobs&#8216; menu item located under &#8216;goodies&#8216; on the main menu: Before we add]]></description> <content:encoded><![CDATA[<p>To do daily database backups, I use cron jobs.  If you aren&#8217;t familiar with cron jobs, think of the as scripts that run on a timer.  Much like &#8216;scheduled tasks&#8217; on windows.  To edit your cron jobs on dreamhost, locate the &#8216;<b>cron jobs</b>&#8216; menu item located under &#8216;<b>goodies</b>&#8216; on the main menu:</p><p><img src='http://www.doknowevil.net/wp-content/uploads/2007/12/dreamhost_cron_jobs.png' alt='Location of cron jobs on dreamhost' /></p><p>Before we add a cron job though, I want to familiarize you with the script and have you run a test to save you a headache later.</p><pre class="brush:bash">
#! /bin/sh

# Daily backups on your database with email notification
# Tyler Mulligan

# file
dateVar=$(date +%m-%d)          # Date variable to append to filename (default: month-day | 11-24)
savePath=&quot;/home/tyler/backups/&quot; # Backups are stored here
fileName=&quot;my_db_backup&quot;         # File name minus the date

# email
subject=&quot;My Database Backup ${dateVar}&quot;
email=&quot;db_robot@mydomain.com&quot;

# database
username=&quot;root&quot;      # username
password=&quot;&quot;          # password
hostname=&quot;localhost&quot; # hostname
database=&quot;database&quot;  # database

mysqldump -u $username -p$password -h $hostname $database | gzip  &gt; $savePath$fileName-$dateVar.sql.gz

uuencode $savePath$fileName-$dateVar.sql.gz $fileName-$dateVar.sql.gz | mail -s &quot;$subject&quot; $email
</pre><p>I&#8217;ve set it up so you fill out your information like any other config file, the last two lines do all the work.</p><p>I suggest you create a new text file called &#8216;dbbackup.txt&#8217;, and paste the above code in and saving it for future reference.  It&#8217;s always good to have a clean slate to start from.  Once you have that done, fill in your file, email and database variables and give it a test run.</p><p><b>Create a shell script through ssh and run that.</b></p><p>Copy your personalized database dump code, log into your server and type:</p><pre>
vi my_db_test.sh
[press i]
right click (to paste the copied code)
[press esc][type &quot;:wq&quot;]
[press enter]
</pre><p>Your script is now written to a file called &#8216;my_db_test.sh&#8217;.</p><p>chmod +x the file and run it:</p><pre>
chmod +x my_db_test.sh
./my_db_test.sh
</pre><p>Once you receive the email, check your backup directory and verify that the database was properly dumped.  If you don&#8217;t receive and email, you did something wrong.</p><p>If everything worked fine, return to the dreamhost cron job page, add a cron job and paste your working code into your newly created cron job.</p><p><a href='http://www.doknowevil.net/wp-content/uploads/2007/12/dreamhost_cron_jobs_2.png' title='A new cron job on dreamhost'><img src='http://www.doknowevil.net/wp-content/uploads/2007/12/dreamhost_cron_jobs_2-150x150.png' alt='A new cron job on dreamhost' /></a></p><p>Save, wait a day and you should receive your email.  It&#8217;s a wise idea to grab a copy of your backup every week or so to store locally.</p><p><a href="http://www.dreamhost.com/r.cgi?181568" title="Dreamhost">Dreamhost</a> is actually offering a special for their 10th anniversary right now, 500gb disk space, 5TB transfer for <a href="http://www.dreamhost.com/r.cgi?181568" title="dreamhost - only $5.95 a month">only $5.95 a month</a>.  I&#8217;ve been with them 2 years and I&#8217;ve been pleased.</p> ]]></content:encoded> <wfw:commentRss>http://www.doknowevil.net/2007/12/13/daily-database-backups-on-dreamhost/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Creating MySQL Queries Visually</title><link>http://www.doknowevil.net/2007/06/19/creating-mysql-queries-visually/</link> <comments>http://www.doknowevil.net/2007/06/19/creating-mysql-queries-visually/#comments</comments> <pubDate>Tue, 19 Jun 2007 15:50:32 +0000</pubDate> <dc:creator>Tyler Mulligan</dc:creator> <category><![CDATA[Freeware]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://www.doknowevil.net/2007/06/19/creating-mysql-queries-visually/</guid> <description><![CDATA[Over the past few days, I&#8217;ve been creating some rather large and confusing SQL queries, so I went on a hunt to see if maybe there was a visual aid that would make the selects, joins and sub queries easier. I was a bit disappointed to find that MySQL offered a Query Browser that wasn&#8217;t]]></description> <content:encoded><![CDATA[<p>Over the past few days, I&#8217;ve been creating some rather large and confusing SQL queries, so I went on a hunt to see if maybe there was a visual aid that would make the selects, joins and sub queries easier.  I was a bit disappointed to find that MySQL offered a <a href="http://www.mysql.com/products/tools/query-browser/">Query Browser</a> that wasn&#8217;t available for download&#8230; or was it?</p><p>After a little more research I came about a link to a slightly thinner client in the <a href="http://dev.mysql.com/downloads/gui-tools/5.0.html">developer zone</a> under the Generally Available (GA) license.  I&#8217;ve played around with it a bit and while it wasn&#8217;t exactly what I was looking for, it&#8217;s helped me during those times I don&#8217;t feel like waiting on phpMyAdmin.</p><p>Check out <a href="http://www.mysql.com/products/tools/query-browser/tutorials/build_queries.html">this screencast</a> to get a better idea of how this tool works.  I&#8217;m sure I&#8217;ll grow to like this tool a lot more in the future, I just need to learn more about it&#8217;s functionality.  I thought I&#8217;d pass this tip onto you.</p><p><img src='http://www.doknowevil.net/wp-content/uploads/2007/06/mysql-browser.png' alt='mysql-browser.png' /></p> ]]></content:encoded> <wfw:commentRss>http://www.doknowevil.net/2007/06/19/creating-mysql-queries-visually/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced)
Object Caching 525/564 objects using disk

Served from: www.doknowevil.net @ 2012-02-07 09:46:40 -->
