Compiling MySQL support for Python under OS X Leopard is a pain, and, so far as I can see, there is no handy way to do it with a redistributable universal binary.
So, I decided to call MySQL from within Python using a subprocess. This is the code that I came up with, which should work fine with a default installation of MAMP. It likely has more overhead than using MySQLdb, and would likely choke if you got a really large result-set back. However, I think it will serve my purposes admirably.
#!/usr/bin/env python
from subprocess import Popen, PIPE
# Set the command you need to connect to your database
# WARNING: password will be visible in a process listing!
mysql_cmd_line = "/Applications/MAMP/Library/bin/mysql -u root -p"
mysql_password = "root"
def RunSqlCommand(sql_statement, database=None):
"""Pass in the SQL statement that you would like executed.
Optionally, specify a database to operate on. Returns the result."""
command_list = mysql_cmd_line.split()
if database:
command_list.append(database)
# Run mysql in a subprocess
process = Popen(command_list, stdin=PIPE, stdout=PIPE,
stderr=PIPE, close_fds=True)
# pass it our commands, and get the results
(stdout, stderr) = process.communicate( mysql_password )
return stdout
def test():
"""Performs a simple test connection."""
print "This specified MySQL server has the following databases:"
print
print RunSqlCommand("SHOW DATABASES;")
print RunSqlCommand("SELECT * FROM USER_PRIVILEGES LIMIT 2;", "information_schema")
if __name__ == "__main__":
test()
The output of that command, against a pristine MAMP installation, is:
This specified MySQL server has the following databases: Database information_schema mysql test GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE 'root'@'localhost' NULL SELECT YES 'root'@'localhost' NULL INSERT YES
This stackoverflow question (http://stackoverflow.com/questions/619804/supplying-password-to-wrapped-up-mysql) explains a small modification that prevents your password from showing up in a process list.
ReplyDeletethe example above cannot work as written.
ReplyDeleteYou are never passing param #1 (sql_statement) to the communicate() method