<?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>PlanetMysql.ru - информация о СУБД MySQL &#187; Python</title>
	<atom:link href="http://planetmysql.ru/category/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://planetmysql.ru</link>
	<description>Блог о самой популярной СУБД MySQL</description>
	<lastBuildDate>Fri, 25 May 2012 06:11:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>MySQL Utilities and Global Transaction Identifiers</title>
		<link>http://drcharlesbell.blogspot.com/2012/04/mysql-utilities-and-global-transaction.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-utilities-and-global-transaction-identifiers</link>
		<comments>http://drcharlesbell.blogspot.com/2012/04/mysql-utilities-and-global-transaction.html#comments</comments>
		<pubDate>Tue, 10 Apr 2012 15:40:00 +0000</pubDate>
		<dc:creator>Chuck Bell</dc:creator>
				<category><![CDATA[gtid]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Replication]]></category>
		<category><![CDATA[workbench]]></category>

		<guid isPermaLink="false">http://planetmysql.ru/?guid=e866e179ab02f5f828e05b344735922a</guid>
		<description><![CDATA[The new MySQL 5.6 Development Milestone Release (DMR) includes many new enhancements. One of the most impressive is the use of Global Transaction Identifiers (GTIDs) for replication. With GTIDs enabled, administrators no longer need to keep track of binary log files and positions. In a nutshell, GTIDs simplify the setup and maintenance of replication.MySQL Utilities has taken this a step further by providing two new utilities that automate two of the most complex replication administration tasks - switchover and failover. Switchover is changing the role of an active, healthy master to one of its slaves whereas failover is the act of promoting a candidate slave to become the new master. Clearly, switchover is an elective operation and failover is performed when there are issues with the master.The GTID utilities are included in release-1.0.5 of MySQL Utilities. They are included as a plugin for MySQL Workbench or via source download from launchpad (see below). The new GTID utilities are included in Workbench version 5.2.39.Automatic Failover UtilityThe most impressive utility is mysqlfailover, It is an interactive tool used to report replication health, report GTIDs in use, and perform automatic failover. Yes, that’s right - you can setup mysqlfailover to automatically failover to one of a specific set of slaves whenever the master goes offline. It is designed to work with the MySQL 5.6.5 and later versions of the server.As you can see in the screenshot, a list is presented including the host, port, role, state, and replication health for each server in the topology. The utility connects to a single master and its slaves. When used in multiple tier environments, users can run an instance for each master. The utility provides the ability to run a failover check and report health at specific intervals in seconds from five seconds and upTo start the utility, users can specify a list of slaves or provide a default user and password to be used in discovering the slaves connected to the master. Discovery of slaves requires the slaves to report the correct host and port when connecting to the master. Along with the list of slaves, the user can specify a list of servers to be used as candidates for selecting a new master when a failover event is detected.Finally, the user can control how failover occurs with the failover mode. The auto mode tells the utility to failover to the list of candidates first and if none are viable, search the list of slaves for a candidate. The elect mode limits election to the candidate slave list and if none are viable, failover does not occur. The fail mode tells the utility to not perform failover and instead stop execution.Along with these options are four extension points permitting users to interact with the utility during failover. These extension points permit users to specify a script to run at each of the following events.exec-fail-check - execute a script to determine if failover is needed. This replaces the default downed master detection and allows users to perform application-specific detection for failover.exec-before - execute a script before failover is performed. This can be used to tell the application to cease write attempts while a new master is setup.exec-after - execute a script immediately after failover to a new master. This permits users to inform the application that the new master is ready.exec-post-fail - execute a script after failover is complete and all slaves have been attached to the new master. This can be used to inform applications that use read-level scale out that it is safe to resume reads from the slaves.The combination of options to control failover, the option to perform automatic failover, and the ability to inform applications of the failover event are powerful features that enable unattended automatic failover for critical replication-based applications. Replication Administration UtilityThe other utility, mysqlrpladmin, is used to perform switchover and failover operations and more on-demand permitting administrators to execute these tasks with a single command. You can use the command to perform one of the following commands.elect - This command is available to only those servers supporting global transaction identifiers (GTIDs), perform best slave election and report best slave to use in the event a switchover or failover is required. Best slave election is simply the first slave to meet the prerequisites.failover - This command is available to only those servers supporting GTIDs. Conduct failover to the best slave. The command will test each candidate slave listed for the prerequisites. Once a candidate slave is elected, it is made a slave of each of the other slaves thereby collecting any transactions executed on other slaves but not the candidate. In this way, the candidate becomes the most up-to-date slave.gtid - This command is available to only those servers supporting GTIDs. It displays the contents of the GTID variables used to report GTIDs in replication. The command also displays universally unique identifiers (UUIDs) for all servers.health - Display the replication health of the topology.reset - Execute the STOP SLAVE and RESET SLAVE commands on all slaves.start - Execute the START SLAVE command on all slaves.stop - Execute the STOP SLAVE command on all slaves.switchover - Perform slave promotion to a specified candidate slave as designated by the --new-master option. This command is available for both gtid-enabled servers and non-gtid-enabled scenarios.These two utilities raise the bar for replication ease of use making the administrator’s job easier. How Can I Get MySQL Utilities?You can check out these new utilities and the entire suite of utilities by either downloading the source code from launchpad or by downloading and installing MySQL Workbench.You can download MySQL Workbench from:http://www.mysql.com/downloads/workbench/You can also download the latest development source code tree for the MySQL Workbench Utilities from:https://launchpad.net/mysql-utilitiesTo learn more about all of the great new replication features in MySQL 5.6, check out the developer zone article at:http://dev.mysql.com/tech-resources/articles/mysql-5.6-replication.html]]></description>
			<content:encoded><![CDATA[The new MySQL 5.6 Development Milestone Release (DMR) includes many new enhancements. One of the most impressive is the use of Global Transaction Identifiers (GTIDs) for replication. With GTIDs enabled, administrators no longer need to keep track of binary log files and positions. In a nutshell, GTIDs simplify the setup and maintenance of replication.<br /><br />MySQL Utilities has taken this a step further by providing two new utilities that automate two of the most complex replication administration tasks - switchover and failover. Switchover is changing the role of an active, healthy master to one of its slaves whereas failover is the act of promoting a candidate slave to become the new master. Clearly, switchover is an elective operation and failover is performed when there are issues with the master.<br /><br />The GTID utilities are included in release-1.0.5 of MySQL Utilities. They are included as a plugin for MySQL Workbench or via source download from launchpad (see below). The new GTID utilities are included in Workbench version 5.2.39.<br /><br /><b>Automatic Failover Utility</b><br />The most impressive utility is mysqlfailover, It is an interactive tool used to report replication health, report GTIDs in use, and perform automatic failover. Yes, that’s right - you can setup mysqlfailover to automatically failover to one of a specific set of slaves whenever the master goes offline. It is designed to work with the MySQL 5.6.5 and later versions of the server.<br /><br /><img alt="failover-2012-04-3-20-40.png" height="304" src="https://lh6.googleusercontent.com/-68mhZR0DRh4/T4QtTAg5EuI/AAAAAAAAAAk/zikW2O0ipww/failover-2012-04-3-20-40.png" width="512" /><br /><br />As you can see in the screenshot, a list is presented including the host, port, role, state, and replication health for each server in the topology. The utility connects to a single master and its slaves. When used in multiple tier environments, users can run an instance for each master. The utility provides the ability to run a failover check and report health at specific intervals in seconds from five seconds and up<br /><br />To start the utility, users can specify a list of slaves or provide a default user and password to be used in discovering the slaves connected to the master. Discovery of slaves requires the slaves to report the correct host and port when connecting to the master. Along with the list of slaves, the user can specify a list of servers to be used as candidates for selecting a new master when a failover event is detected.<br /><br />Finally, the user can control how failover occurs with the failover mode. The <i>auto</i> mode tells the utility to failover to the list of candidates first and if none are viable, search the list of slaves for a candidate. The <i>elect</i> mode limits election to the candidate slave list and if none are viable, failover does not occur. The fail mode tells the utility to not perform failover and instead stop execution.<br /><br />Along with these options are four extension points permitting users to interact with the utility during failover. These extension points permit users to specify a script to run at each of the following events.<br /><ul><li><b>exec-fail-check </b>- execute a script to determine if failover is needed. This replaces the default downed master detection and allows users to perform application-specific detection for failover.</li><li><b>exec-before</b> - execute a script before failover is performed. This can be used to tell the application to cease write attempts while a new master is setup.</li><li><b>exec-after</b> - execute a script immediately after failover to a new master. This permits users to inform the application that the new master is ready.</li><li><b>exec-post-fail</b> - execute a script after failover is complete and all slaves have been attached to the new master. This can be used to inform applications that use read-level scale out that it is safe to resume reads from the slaves.</li></ul>The combination of options to control failover, the option to perform automatic failover, and the ability to inform applications of the failover event are powerful features that enable unattended automatic failover for critical replication-based applications. <br /><br /><b>Replication Administration Utility</b><br />The other utility, mysqlrpladmin, is used to perform switchover and failover operations and more on-demand permitting administrators to execute these tasks with a single command. You can use the command to perform one of the following commands.<br /><ul><li><b>elect</b> - This command is available to only those servers supporting global transaction identifiers (GTIDs), perform best slave election and report best slave to use in the event a switchover or failover is required. Best slave election is simply the first slave to meet the prerequisites.</li><li><b>failover</b> - This command is available to only those servers supporting GTIDs. Conduct failover to the best slave. The command will test each candidate slave listed for the prerequisites. Once a candidate slave is elected, it is made a slave of each of the other slaves thereby collecting any transactions executed on other slaves but not the candidate. In this way, the candidate becomes the most up-to-date slave.</li><li><b>gtid</b> - This command is available to only those servers supporting GTIDs. It displays the contents of the GTID variables used to report GTIDs in replication. The command also displays universally unique identifiers (UUIDs) for all servers.</li><li><b>health</b> - Display the replication health of the topology.</li><li><b>reset</b> - Execute the STOP SLAVE and RESET SLAVE commands on all slaves.</li><li><b>start</b> - Execute the START SLAVE command on all slaves.</li><li><b>stop</b> - Execute the STOP SLAVE command on all slaves.</li><li><b>switchover</b> - Perform slave promotion to a specified candidate slave as designated by the --new-master option. This command is available for both gtid-enabled servers and non-gtid-enabled scenarios.</li></ul>These two utilities raise the bar for replication ease of use making the administrator’s job easier. <br /><br /><b>How Can I Get MySQL Utilities?</b><br />You can check out these new utilities and the entire suite of utilities by either downloading the source code from launchpad or by downloading and installing MySQL Workbench.<br /><br />You can download MySQL Workbench from:<br /><br /><a href="http://www.mysql.com/downloads/workbench/">http://www.mysql.com/downloads/workbench/</a><br /><br />You can also download the latest development source code tree for the MySQL Workbench Utilities from:<br /><br /><a href="https://launchpad.net/mysql-utilities">https://launchpad.net/mysql-utilities</a><br /><br />To learn more about all of the great new replication features in MySQL 5.6, check out the developer zone article at:<br /><br /><a href="http://dev.mysql.com/tech-resources/articles/mysql-5.6-replication.html">http://dev.mysql.com/tech-resources/articles/mysql-5.6-replication.html</a><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/2959317805805542041-4419666669436002132?l=drcharlesbell.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=32796&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=32796&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2012/04/10/mysql-utilities-and-global-transaction-identifiers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Splitmytab ready for the public!</title>
		<link>http://www.rustyrazorblade.com/2012/02/splitmytab-ready-for-the-public/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=splitmytab-ready-for-the-public</link>
		<comments>http://www.rustyrazorblade.com/2012/02/splitmytab-ready-for-the-public/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 19:37:35 +0000</pubDate>
		<dc:creator>Jonathan Haddad</dc:creator>
				<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[splitmytab]]></category>
		<category><![CDATA[tornado]]></category>

		<guid isPermaLink="false">http://www.rustyrazorblade.com/?p=1601</guid>
		<description><![CDATA[Splitmytab.net is finally for the public to check out.  Splitmytab is a bill splitting and IOU system for friends.  It uses facebook&#8217;s login, so you won&#8217;t need to put in anyone&#8217;s emails, names, or get people to sign up for an account.
It&#8217;ll automatically keep balances of who owes who, so you can keep a running tab with friends and always know who&#8217;s buying the next case of beer.
Please note: I&#8217;m not a designer, so there&#8217;s a few rough corners, but what&#8217;s there is simple and it works.  
Tech Notes:

Backend is MySQL 5.5
Written in Python
Nginx with tornado
Redis used on occasion
Originally was writing pure JS then switched to Coffeescript

Enjoy, and please leave feedback!]]></description>
			<content:encoded><![CDATA[<p>Splitmytab.net is finally for the public to check out.  Splitmytab is a bill splitting and IOU system for friends.  It uses facebook&#8217;s login, so you won&#8217;t need to put in anyone&#8217;s emails, names, or get people to sign up for an account.</p>
<p>It&#8217;ll automatically keep balances of who owes who, so you can keep a running tab with friends and always know who&#8217;s buying the next case of beer.</p>
<p>Please note: I&#8217;m not a designer, so there&#8217;s a few rough corners, but what&#8217;s there is simple and it works.  </p>
<p>Tech Notes:</p>
<ul>
<li>Backend is MySQL 5.5</li>
<li>Written in Python</li>
<li>Nginx with tornado</li>
<li>Redis used on occasion</li>
<li>Originally was writing pure JS then switched to Coffeescript</li>
</ul>
<p>Enjoy, and please leave feedback!</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=32095&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=32095&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2012/02/21/splitmytab-ready-for-the-public/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Splitmytab ready for the public!</title>
		<link>http://www.rustyrazorblade.com/2012/02/splitmytab-ready-for-the-public/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=splitmytab-ready-for-the-public</link>
		<comments>http://www.rustyrazorblade.com/2012/02/splitmytab-ready-for-the-public/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 19:37:35 +0000</pubDate>
		<dc:creator>Jonathan Haddad</dc:creator>
				<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[splitmytab]]></category>
		<category><![CDATA[tornado]]></category>

		<guid isPermaLink="false">http://www.rustyrazorblade.com/?p=1601</guid>
		<description><![CDATA[Splitmytab.net is finally for the public to check out.  Splitmytab is a bill splitting and IOU system for friends.  It uses facebook&#8217;s login, so you won&#8217;t need to put in anyone&#8217;s emails, names, or get people to sign up for an account.
It&#8217;ll automatically keep balances of who owes who, so you can keep a running tab with friends and always know who&#8217;s buying the next case of beer.
Please note: I&#8217;m not a designer, so there&#8217;s a few rough corners, but what&#8217;s there is simple and it works.  
Tech Notes:

Backend is MySQL 5.5
Written in Python
Nginx with tornado
Redis used on occasion
Originally was writing pure JS then switched to Coffeescript

Enjoy, and please leave feedback!]]></description>
			<content:encoded><![CDATA[<p>Splitmytab.net is finally for the public to check out.  Splitmytab is a bill splitting and IOU system for friends.  It uses facebook&#8217;s login, so you won&#8217;t need to put in anyone&#8217;s emails, names, or get people to sign up for an account.</p>
<p>It&#8217;ll automatically keep balances of who owes who, so you can keep a running tab with friends and always know who&#8217;s buying the next case of beer.</p>
<p>Please note: I&#8217;m not a designer, so there&#8217;s a few rough corners, but what&#8217;s there is simple and it works.  </p>
<p>Tech Notes:</p>
<ul>
<li>Backend is MySQL 5.5</li>
<li>Written in Python</li>
<li>Nginx with tornado</li>
<li>Redis used on occasion</li>
<li>Originally was writing pure JS then switched to Coffeescript</li>
</ul>
<p>Enjoy, and please leave feedback!</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=32095&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=32095&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2012/02/21/splitmytab-ready-for-the-public/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pythonic Database API: Now with Launchpad</title>
		<link>http://mysqlmusings.blogspot.com/2012/02/pythonic-database-api-now-with.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pythonic-database-api-now-with-launchpad</link>
		<comments>http://mysqlmusings.blogspot.com/2012/02/pythonic-database-api-now-with.html#comments</comments>
		<pubDate>Mon, 20 Feb 2012 20:24:00 +0000</pubDate>
		<dc:creator>Mats Kindahl</dc:creator>
				<category><![CDATA[api]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://planetmysql.ru/?guid=36e16e71028ae5084e62b79cbbb00567</guid>
		<description><![CDATA[In a previous post, I demonstrated a simple Python database API with a syntax similar to jQuery.  The goal was to provide a simple API that would allow Python programmers to use a database without having to resort to SQL, nor having to use any of the good, but quite heavy, ORM implementations that exist.  The code was just an experimental implementation, and I was considering putting it up on Launchpad.

I did some basic cleaning of the code, turned it into a Python package, and pushed it to Launchpad. I also added some minor changes, such as introducing a define function to define new tables instead of automatically creating one when an insert was executed.  Automatically constructing a table from values seems neat, but in reality it is quite difficult to ensure that it has the right types for the application. Here is a small code example demonstrating how to use the define function together with some other operations.


import mysql.api.simple as api

server = api.Server(host="example.com")

server.test_api.tbl.define(
    { 'name': 'more', 'type': int },
    { 'name': 'magic', 'type': str },
    )

items = [
    {'more': 3, 'magic': 'just a test'},
    {'more': 3, 'magic': 'just another test'},
    {'more': 4, 'magic': 'quadrant'},
    {'more': 5, 'magic': 'even more magic'},
    ]

for item in items:
    server.test_api.tbl.insert(item)


The table is defined by providing a dictionary for each row that you want in the table. The two most important fields in the dictionary is name and type. The name field is used to supply a name for the field, and the type field is used to provide a type of the column. The type is denoted using a basic Python type constructor, which then maps internally to a SQL type. So, for example, int map to the SQL INT type, and bool map to the SQL type BIT(1).  This choice of deciding to use Python types are simply because it is more natural for a Python programmer to define the tables from the data that the programmer want to store in the database. I this case, I would be less concerned with how the types are mapped, just assuming that it is mapped in a way that works.  It is currently not possible to register your own mappings, but that is easy to add.

So, why provide the type object and not just a string with the type name? The idea I had here is that since Python has introspection (it is a dynamic language after all), it would be possible to add code that read the provided type objects and do things with them, such as figuring out what fields there are in the type. It's not that I plan to implement this, but even though this is intended to be a simple database interface, there is no reason to tie ones hands from start, so this simple approach will provide some flexibility if needed in the future.

Links

Some additional links that you might find useful:


  Connector/Python
  You need to have Connector/Python installed to be able to use this package.
  Sequalize
  This is a JavaScript library that provide a similar interface to a database. It claims to be an ORM layer, but is not really. It is more similar to what I have written above.
  Roland's MQL to SQL and Presentation on SlideShare is also some inspiration for alternatives.]]></description>
			<content:encoded><![CDATA[In a <a href="http://mysqlmusings.blogspot.com/2011/09/python-interface-to-mysql.html">previous post</a>, I demonstrated a simple Python database API with a syntax similar to jQuery.  The goal was to provide a simple API that would allow Python programmers to use a database without having to resort to SQL, nor having to use any of the good, but quite heavy, ORM implementations that exist.  The code was just an experimental implementation, and I was considering putting it up on Launchpad.<p>

I did some basic cleaning of the code, turned it into a Python package, and <a href="https://launchpad.net/mysql-python-api">pushed it to Launchpad</a>. I also added some minor changes, such as introducing a <code>define</code> function to define new tables instead of automatically creating one when an insert was executed.  Automatically constructing a table from values seems neat, but in reality it is quite difficult to ensure that it has the right types for the application. Here is a small code example demonstrating how to use the <code>define</code> function together with some other operations.

<pre>
import mysql.api.simple as api

server = api.Server(host="example.com")

<em>server.test_api.tbl.define(
    { 'name': 'more', 'type': int },
    { 'name': 'magic', 'type': str },
    )</em>

items = [
    {'more': 3, 'magic': 'just a test'},
    {'more': 3, 'magic': 'just another test'},
    {'more': 4, 'magic': 'quadrant'},
    {'more': 5, 'magic': 'even more magic'},
    ]

for item in items:
    server.test_api.tbl.insert(item)
</pre>

The table is defined by providing a dictionary for each row that you want in the table. The two most important fields in the dictionary is <var>name</var> and <var>type</var>. The <var>name</var> field is used to supply a name for the field, and the <var>type</var> field is used to provide a type of the column. The type is denoted using a basic Python type constructor, which then maps internally to a SQL type. So, for example, <code>int</code> map to the SQL <code>INT</code> type, and <code>bool</code> map to the SQL type <code>BIT(1)</code>.  This choice of deciding to use Python types are simply because it is more natural for a Python programmer to define the tables from the data that the programmer want to store in the database. I this case, I would be less concerned with how the types are mapped, just assuming that it is mapped in a way that works.  It is currently not possible to register your own mappings, but that is easy to add.<p>

So, why provide the type object and not just a string with the type name? The idea I had here is that since Python has introspection (it is a dynamic language after all), it would be possible to add code that read the provided type objects and do things with them, such as figuring out what fields there are in the type. It's not that I plan to implement this, but even though this is intended to be a simple database interface, there is no reason to tie ones hands from start, so this simple approach will provide some flexibility if needed in the future.

<h2>Links</h2>

Some additional links that you might find useful:

<dl>
  <dt><a href="http://launchpad.net/myconnpy">Connector/Python</a>
  <dd>You need to have Connector/Python installed to be able to use this package.
  <dt><a href="http://sequelizejs.com">Sequalize</a>
  <dd>This is a JavaScript library that provide a similar interface to a database. It claims to be an ORM layer, but is not really. It is more similar to what I have written above.
  <dt><a href="http://rpbouman.blogspot.com/">Roland's</a> <a href="http://code.google.com/p/mql-to-sql/">MQL to SQL</a> and <a href="http://www.slideshare.net/rpbouman/mql-tosql-a-jsonbased-rdbms-query-language">Presentation on SlideShare</a> is also some inspiration for alternatives.
  <dt>
  <dd>
  <dd>
</dl>
<div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/23496029-603222833098461547?l=mysqlmusings.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=32070&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=32070&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2012/02/20/pythonic-database-api-now-with-launchpad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL: Python, Meta-Programming, and Interceptors</title>
		<link>http://mysqlmusings.blogspot.com/2012/01/mysql-python-meta-programming-and.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-python-meta-programming-and-interceptors</link>
		<comments>http://mysqlmusings.blogspot.com/2012/01/mysql-python-meta-programming-and.html#comments</comments>
		<pubDate>Mon, 23 Jan 2012 20:55:00 +0000</pubDate>
		<dc:creator>Mats Kindahl</dc:creator>
				<category><![CDATA[connector]]></category>
		<category><![CDATA[interceptor]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://planetmysql.ru/?guid=13e6b696138aee4a31ea45b7f36cdff1</guid>
		<description><![CDATA[I recently found Todd's posts on interceptors which allow callbacks (called interceptors) to be registered with the connector so that you can intercept a statement execution, commit, or any of the many extension points supported by Connector/Java.  This is a language feature that allow you to implement a number of new features without having to change the application code such as load-balancing policies, profiling queries or transactions, or debugging an application.

Since Python is a dynamic language, it is easy to add interceptors to any method in Connector/Python, without having to extend the connector with specific code. This is something that is possible in dynamic languages such as Python, Perl, JavaScript, and even some lesser known languages such as Lua and Self. In this post, I will describe how and also give an introduction to some of the (in my view) more powerful features of Python.

In order to create an interceptor, you need to be able to do these things:


  Catch an existing method in a class and replace it with a new one.
  Call the original function, if necessary.
  For extra points: catch an existing method in an object and replace a new one.


You will in this post see how all three of these problems are solved in Python. You will see and use decorators to be able to define methods in existing classes and object, and closures to be able to call the original version of the methods.  By picking this approach, it will not be necessary to change the implementation: in fact, you can use this code to replace any method in any class, not only in Connector/Python.


Table 1. Attributes for methods

  
  Method Instance


  Name
  Unbound
  Bound

  __name__
  Name of Method


  im_func
  "Inner" function of the method


  im_self
  None
  Class instance for the method


  im_class
  Class that the method belongs to



In addition to being able to replace methods in the class, we would also like to be able to replace methods in instances of a class ("objects" in the traditional sense). This is useful to create specialized objects, for example for tracking particular cases where a method is used.

In order to understand how the replacement works, you should understand that in Python (and the dynamic languages mentioned above), all objects can have attributes, including classes, functions, and a bunch of other esoteric constructions. Each type of object has a set of pre-defined attributes with well-defined meaning. For classes (and class instances), methods are stored as attributes of the class (or class instance) and can therefore be replaced with other methods that you build dynamically. However, it requires some tinkering to take an existing "normal" function definition and "imbue" it with whatever "tincture" that makes it behave as a method of the class or class instance.

Depending on where the method comes from, it can be either unbound and bound. Unbound methods are roughly equivalent to member function pointers in C++: they reference a function, but not the instance. In contrast, bound methods have an instance tied to it, so when you call them, they already know what instance they belong to and will use it. Methods have a set of attributes, of which the four in Table&#160;1 interests us.  If a method is fetched from a class (to be precise, from a class object), it will be unbound and im_self will be None. If the method is fetched from a class instance, it will be bound and im_self will be set to the instance it belongs to. These attributes are all the "tincture" you need make our own instance methods.

The code for doing the replacement described above is simply:


import functools, types

def replace_method(orig, func)
    functools.update_wrapper(func, orig.im_func)
    new = types.MethodType(func, orig.im_self, orig.im_class)
    obj = orig.im_self or orig.im_class
    setattr(obj, orig.__name__, new)


The function uses two standard modules to make the job simpler, but the steps are:

  Copy the meta-information from the original method function to the new function using update_wrapper. This copies the name, module information, and documentation from the original method function to make it look like the original method.
  Create a new method instance from the method information of the original method using the constructor MethodType, but replace the "inner" function with the new function.
  Install the new instance method in the class or instance by replacing the attribute denoting the original method with the new method.  Depending on whether the function is given a bound or unbound instance, either the method in the class or in the instance is replaced.


Using this function you can now replace a method in a class like this:


from mysql.connector import MySQLCursor

def my_execute(self, operation, params=None):
  ...

replace_method(MySQLCursor.execute, my_execute)


This is already pretty useful, but note that you can also replace only a specific instance as well by using replace_method(cursor.execute, my_execute). It was not necessary to change anything inside Connector/Python to intercept a method there, so you can actually apply this to any method in any of the classes in Connector/Python that you already have available.  In order to make it even easier to use you'll see how to define a decorator that will install the function in the correct place at the same time as it is defined. The code for defining a decorator and an example usage is:


import functools, types
from mysql.connector import MySQLCursor

def intercept(orig):
    def wrap(func):
        functools.update_wrapper(func, orig.im_func)
        meth = types.MethodType(func, orig.im_self, orig.im_class)
        obj = orig.im_self or orig.im_class
        setattr(obj, orig.__name__, meth)
        return func
    return wrap

# Define a function using the decorator
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
  ...


The @intercept line before the definition of my_execute is where the new descriptor is used. The syntax is a shorthand that can be used to do some things with the function when defining it. It behaves as if the following code had been executed:


def temporary(self, operation, params=None):
  ...
my_execute = intercept(MySQLCursor.execute)(temporary)


As you can see here, whatever is given after the @ is used as a function and called with the function-being-defined as argument. This explains why the wrap function is returned from the decorator (it will be called with a reference to the function that is being defined), and also why the original function is returned from the wrap function (the result will be assigned to the function name).

Using a statement interceptor, you can catch the execution of statements and do some special magic on them.  In our case, let's define an interceptor to catch the execution of a statement and log the result using the standard logging module. If you read the wrap function carefully, you probably noted that it uses a closure to access the value of orig when the decorator was called, not the value it happen to have when the wrap function is executed. This feature is very useful since a closure can also be used to get access to the original execute function and call it from within the new function.  So, to intercept an execute call and log information about the statement using the logging module, you could use code like this:


from mysql.connector import MySQLCursor
original_execute = MySQLCursor.execute
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
    if params is not None:
        stmt = operation % self._process_params(params)
    else:
        stmt = operation
    result = original_execute(self, operation, params)
    logging.debug("Executed '%s', rowcount: %d", stmt, self.rowcount)
    logging.debug("Columns: %s", ', '. join(c[0] for c in self.description))
    return result


Now with this, you could implement your own caching layer to, for example, do a memcached lookup before sending the statement to the server for execution. I leave this as an exercises to the reader, or maybe I'll show you in a later post. &#38;smiley;

Implementing a lifecycle interceptor is similar, only that you replace, for example, the commit or rollback calls. However, implementing an exception interceptor is not obvious.  Catching the exception is straightforward and can be done using the intercept decorator:


original_init = ProgrammingError.__init__
@intercept(ProgrammingError.__init__)
def catch_error(self, msg, errno):
    logging.debug("This statement didn't work: '%s', errno: %d", msg, errno)
    original_init(self, msg, errno=errno)


However, in order to do something more interesting, such as asking for some additional information from the database, it is necessary to either get hold of the cursor that was used to execute the query, or at least the connection. It is possible to dig through the interpreter stack, or try to override one of the internal methods that Connector/Python uses, but since that is very dependent on the implementation, I will not present that in this post.  It would be good if the cursor is passed down to the exception constructor, but this requires some changes to the connector code.

Even though I have been programming in dynamic languages for decades (literally) it always amaze me how easy it is to accomplish things in these languages. If you are interested in playing around with this code, you can always fetch Connector/Python on Launchpad and try out the examples above. Some links and other assorted references related to this post are:


  Connector/Python is found at launchpad.net/myconnpy
  Geert has a number of excellent posts on Connector/Python under geert.vanderkelen.org. Also, as you might already know, he is now working with developing Connector/Python and he's always interested in comments and suggestions. :)
  Todd's Blog mysqlblog.fivefarmers.com is always interesting to read, and these articles on interceptors are the ones I read
  
    Lifecycle Interceptors
    Statement Interceptors
    Exception Interceptors]]></description>
			<content:encoded><![CDATA[I recently found Todd's <a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/">posts</a> <a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/">on</a> <a href="http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%E2%80%93-exception-interceptors/">interceptors</a> which allow callbacks (called <em>interceptors</em>) to be registered with the connector so that you can intercept a statement execution, commit, or any of the many extension points supported by Connector/Java.  This is a language feature that allow you to implement a number of new features without having to change the application code such as load-balancing policies, profiling queries or transactions, or debugging an application.<p>

Since Python is a dynamic language, it is easy to add interceptors to <em>any</em> method in Connector/Python, without having to extend the connector with specific code. This is something that is possible in dynamic languages such as Python, Perl, JavaScript, and even some lesser known languages such as Lua and Self. In this post, I will describe how and also give an introduction to some of the (in my view) more powerful features of Python.<p>

In order to create an interceptor, you need to be able to do these things:

<ul>
  <li>Catch an existing method in a class and replace it with a new one.</li>
  <li>Call the original function, if necessary.</li>
  <li>For extra points: catch an existing method in an <em>object</em> and replace a new one.</li>
</ul>

You will in this post see how all three of these problems are solved in Python. You will see and use <em>decorators</em> to be able to define methods in existing classes and object, and closures to be able to call the original version of the methods.  By picking this approach, it will not be necessary to change the implementation: in fact, you can use this code to replace <em>any</em> method in <em>any</em> class, not only in Connector/Python.<p>

<table border="" width="">
<caption>Table 1. Attributes for methods</caption>
<TR>
  <TH></TH>
  <TH colspan="2">Method Instance</TH>
</TR>
<TR>
  <TH>Name</TH>
  <TH>Unbound</TH>
  <TH>Bound</TH></TR>
<TR>
  <TD><code>__name__</code></TD>
  <TD align="center" colspan="2">Name of Method</TD>
</TR>
<TR>
  <TD><code>im_func</code></TD>
  <TD align="center" colspan="2">"Inner" function of the method</TD>
</TR>
<TR>
  <TD><code>im_self</code></TD>
  <TD><code>None</code></TD>
  <TD align="center">Class instance for the method</TD>
</TR>
<TR>
  <TD><code>im_class</code></TD>
  <TD align="center" colspan="2">Class that the method belongs to</TD>
</TR>
</table>

In addition to being able to replace methods in the class, we would also like to be able to replace methods in instances of a class ("objects" in the traditional sense). This is useful to create specialized objects, for example for tracking particular cases where a method is used.<p>

In order to understand how the replacement works, you should understand that in Python (and the dynamic languages mentioned above), all objects can have attributes, including classes, functions, and a bunch of other esoteric constructions. Each type of object has a set of pre-defined attributes with well-defined meaning. For classes (and class instances), methods are stored as attributes of the class (or class instance) and can therefore be replaced with other methods that you build dynamically. However, it requires some tinkering to take an existing "normal" function definition and "imbue" it with whatever "tincture" that makes it behave as a method of the class or class instance.<p>

Depending on where the method comes from, it can be either <em>unbound</em> and <em>bound</em>. Unbound methods are roughly equivalent to member function pointers in C++: they reference a function, but not the instance. In contrast, bound methods have an instance tied to it, so when you call them, they already know what instance they belong to and will use it. Methods have a set of attributes, of which the four in Table&nbsp;1 interests us.  If a method is fetched from a class (to be precise, from a class object), it will be unbound and <code>im_self</code> will be <code>None</code>. If the method is fetched from a class <em>instance</em>, it will be bound and <code>im_self</code> will be set to the instance it belongs to. These attributes are all the "tincture" you need make our own instance methods.

The code for doing the replacement described above is simply:

<pre>
<code>import</code> functools, types

<code>def</code> replace_method(orig, func)
    functools.update_wrapper(func, orig.im_func)
    new = types.MethodType(func, orig.im_self, orig.im_class)
    obj = orig.im_self or orig.im_class
    setattr(obj, orig.__name__, new)
</pre>

The function uses two standard modules to make the job simpler, but the steps are:
<ol>
  <li>Copy the meta-information from the original method function to the new function using <code>update_wrapper</code>. This copies the name, module information, and documentation from the original method function to make it look like the original method.</li>
  <li>Create a new method instance from the method information of the original method using the constructor <code>MethodType</code>, but replace the "inner" function with the new function.</li>
  <li>Install the new instance method in the class or instance by replacing the attribute denoting the original method with the new method.  Depending on whether the function is given a bound or unbound instance, either the method in the class or in the instance is replaced.</li>
</ol>

Using this function you can now replace a method in a class like this:

<pre>
<code>from</code> mysql.connector <code>import</code> MySQLCursor

<code>def</code> my_execute(self, operation, params=None):
  ...

replace_method(MySQLCursor.execute, my_execute)
</pre>

This is already pretty useful, but note that you can also replace only a specific instance as well by using <code>replace_method(cursor.execute, my_execute)</code>. It was not necessary to change anything inside Connector/Python to intercept a method there, so you can actually apply this to any method in any of the classes in Connector/Python that you already have available.  In order to make it even easier to use you'll see how to define a <em>decorator</em> that will install the function in the correct place at the same time as it is defined. The code for defining a decorator and an example usage is:

<pre>
<code>import</code> functools, types
<code>from</code> mysql.connector <code>import</code> MySQLCursor

<code>def</code> intercept(orig):
    <code>def</code> wrap(func):
        functools.update_wrapper(func, orig.im_func)
        meth = types.MethodType(func, orig.im_self, orig.im_class)
        obj = orig.im_self or orig.im_class
        setattr(obj, orig.__name__, meth)
        return func
    return wrap

<span># Define a function using the decorator</span>
@intercept(MySQLCursor.execute)
<code>def</code> my_execute(self, operation, params=None):
  ...
</pre>

The <code>@intercept</code> line before the definition of <code>my_execute</code> is where the new descriptor is used. The syntax is a shorthand that can be used to do some things with the function when defining it. It behaves as if the following code had been executed:

<pre>
<code>def</code> <var>temporary</var>(self, operation, params=None):
  ...
my_execute = intercept(MySQLCursor.execute)(<var>temporary</var>)
</pre>

As you can see here, whatever is given after the <code>@</code> is used as a function and called with the function-being-defined as argument. This explains why the <code>wrap</code> function is returned from the decorator (it will be called with a reference to the function that is being defined), and also why the original function is returned from the <code>wrap</code> function (the result will be assigned to the function name).<p>

Using a statement interceptor, you can catch the execution of statements and do some special magic on them.  In our case, let's define an interceptor to catch the execution of a statement and log the result using the standard <a href="http://docs.python.org/library/logging.html"><code>logging</code></a> module. If you read the <code>wrap</code> function carefully, you probably noted that it uses a <dfn>closure</dfn> to access the value of <var>orig</var> when the decorator was <em>called</em>, not the value it happen to have when the <>wrap</code> function is executed. This feature is very useful since a closure can also be used to get access to the original <code>execute</code> function and call it from within the new function.  So, to intercept an execute call and log information about the statement using the <a href="http://docs.python.org/library/logging.html"><code>logging</code></a> module, you could use code like this:

<pre>
from mysql.connector import MySQLCursor
original_execute = MySQLCursor.execute
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
    if params is not None:
        stmt = operation % self._process_params(params)
    else:
        stmt = operation
    result = original_execute(self, operation, params)
    logging.debug("Executed '%s', rowcount: %d", stmt, self.rowcount)
    logging.debug("Columns: %s", ', '. join(c[0] for c in self.description))
    return result
</pre>

Now with this, you could implement your own caching layer to, for example, do a memcached lookup before sending the statement to the server for execution. I leave this as an exercises to the reader, or maybe I'll show you in a later post. &smiley;

Implementing a lifecycle interceptor is similar, only that you replace, for example, the commit or rollback calls. However, implementing an exception interceptor is not obvious.  Catching the exception is straightforward and can be done using the <code>intercept</code> decorator:

<pre>
original_init = ProgrammingError.__init__
@intercept(ProgrammingError.__init__)
def catch_error(self, msg, errno):
    logging.debug("This statement didn't work: '%s', errno: %d", msg, errno)
    original_init(self, msg, errno=errno)
</pre>

However, in order to do something more interesting, such as asking for some additional information from the database, it is necessary to either get hold of the cursor that was used to execute the query, or at least the connection. It is possible to dig through the interpreter stack, or try to override one of the internal methods that Connector/Python uses, but since that is very dependent on the implementation, I will not present that in this post.  It would be good if the cursor is passed down to the exception constructor, but this requires some changes to the connector code.<p>

Even though I have been programming in dynamic languages for decades (literally) it always amaze me how easy it is to accomplish things in these languages. If you are interested in playing around with this code, you can always fetch Connector/Python on Launchpad and try out the examples above. Some links and other assorted references related to this post are:

<ul>
  <li>Connector/Python is found at <a href="https://launchpad.net/myconnpy">launchpad.net/myconnpy</a></li>
  <li>Geert has a number of excellent posts on Connector/Python under <a href="http://geert.vanderkelen.org/">geert.vanderkelen.org</a>. Also, <a href="http://geert.vanderkelen.org/post/817">as you might already know</a>, he is now working with developing Connector/Python and he's always interested in comments and suggestions. :)
  <li>Todd's Blog <a href="http://mysqlblog.fivefarmers.com/">mysqlblog.fivefarmers.com</a> is always interesting to read, and these articles on interceptors are the ones I read
  <ul>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/">Lifecycle Interceptors</a>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/">Statement Interceptors</a>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%E2%80%93-exception-interceptors/">Exception Interceptors</a>
  </ul>
</ul><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/23496029-8853718009688026024?l=mysqlmusings.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=31777&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=31777&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2012/01/23/mysql-python-meta-programming-and-interceptors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL: Python, Meta-Programming, and Interceptors</title>
		<link>http://mysqlmusings.blogspot.com/2012/01/mysql-python-meta-programming-and.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-python-meta-programming-and-interceptors</link>
		<comments>http://mysqlmusings.blogspot.com/2012/01/mysql-python-meta-programming-and.html#comments</comments>
		<pubDate>Mon, 23 Jan 2012 20:55:00 +0000</pubDate>
		<dc:creator>Mats Kindahl</dc:creator>
				<category><![CDATA[connector]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://planetmysql.ru/?guid=13e6b696138aee4a31ea45b7f36cdff1</guid>
		<description><![CDATA[I recently found Todd's posts on interceptors which allow callbacks (called interceptors) to be registered with the connector so that you can intercept a statement execution, commit, or any of the many extension points supported by Connector/Java.  This is a language feature that allow you to implement a number of new features without having to change the application code such as load-balancing policies, profiling queries or transactions, or debugging an application.

Since Python is a dynamic language, it is easy to add interceptors to any method in Connector/Python, without having to extend the connector with specific code. This is something that is possible in dynamic languages such as Python, Perl, JavaScript, and even some lesser known languages such as Lua and Self. In this post, I will describe how and also give an introduction to some of the (in my view) more powerful features of Python.

In order to create an interceptor, you need to be able to do these things:


  Catch an existing method in a class and replace it with a new one.
  Call the original function, if necessary.
  For extra points: catch an existing method in an object and replace a new one.


You will in this post see how all three of these problems are solved in Python. You will see and use decorators to be able to define methods in existing classes and object, and closures to be able to call the original version of the methods.  By picking this approach, it will not be necessary to change the implementation: in fact, you can use this code to replace any method in any class, not only in Connector/Python.


Table 1. Attributes for methods

  
  Method Instance


  Name
  Unbound
  Bound

  __name__
  Name of Method


  im_func
  "Inner" function of the method


  im_self
  None
  Class instance for the method


  im_class
  Class that the method belongs to



In addition to being able to replace methods in the class, we would also like to be able to replace methods in instances of a class ("objects" in the traditional sense). This is useful to create specialized objects, for example for tracking particular cases where a method is used.

In order to understand how the replacement works, you should understand that in Python (and the dynamic languages mentioned above), all objects can have attributes, including classes, functions, and a bunch of other esoteric constructions. Each type of object has a set of pre-defined attributes with well-defined meaning. For classes (and class instances), methods are stored as attributes of the class (or class instance) and can therefore be replaced with other methods that you build dynamically. However, it requires some tinkering to take an existing "normal" function definition and "imbue" it with whatever "tincture" that makes it behave as a method of the class or class instance.

Depending on where the method comes from, it can be either unbound and bound. Unbound methods are roughly equivalent to member function pointers in C++: they reference a function, but not the instance. In contrast, bound methods have an instance tied to it, so when you call them, they already know what instance they belong to and will use it. Methods have a set of attributes, of which the four in Table&#160;1 interests us.  If a method is fetched from a class (to be precise, from a class object), it will be unbound and im_self will be None. If the method is fetched from a class instance, it will be bound and im_self will be set to the instance it belongs to. These attributes are all the "tincture" you need make our own instance methods.

The code for doing the replacement described above is simply:


import functools, types

def replace_method(orig, func)
    functools.update_wrapper(func, orig.im_func)
    new = types.MethodType(func, orig.im_self, orig.im_class)
    obj = orig.im_self or orig.im_class
    setattr(obj, orig.__name__, new)


The function uses two standard modules to make the job simpler, but the steps are:

  Copy the meta-information from the original method function to the new function using update_wrapper. This copies the name, module information, and documentation from the original method function to make it look like the original method.
  Create a new method instance from the method information of the original method using the constructor MethodType, but replace the "inner" function with the new function.
  Install the new instance method in the class or instance by replacing the attribute denoting the original method with the new method.  Depending on whether the function is given a bound or unbound instance, either the method in the class or in the instance is replaced.


Using this function you can now replace a method in a class like this:


from mysql.connector import MySQLCursor

def my_execute(self, operation, params=None):
  ...

replace_method(MySQLCursor.execute, my_execute)


This is already pretty useful, but note that you can also replace only a specific instance as well by using replace_method(cursor.execute, my_execute). It was not necessary to change anything inside Connector/Python to intercept a method there, so you can actually apply this to any method in any of the classes in Connector/Python that you already have available.  In order to make it even easier to use you'll see how to define a decorator that will install the function in the correct place at the same time as it is defined. The code for defining a decorator and an example usage is:


import functools, types
from mysql.connector import MySQLCursor

def intercept(orig):
    def wrap(func):
        functools.update_wrapper(func, orig.im_func)
        meth = types.MethodType(func, orig.im_self, orig.im_class)
        obj = orig.im_self or orig.im_class
        setattr(obj, orig.__name__, meth)
        return func
    return wrap

# Define a function using the decorator
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
  ...


The @intercept line before the definition of my_execute is where the new descriptor is used. The syntax is a shorthand that can be used to do some things with the function when defining it. It behaves as if the following code had been executed:


def temporary(self, operation, params=None):
  ...
my_execute = intercept(MySQLCursor.execute)(temporary)


As you can see here, whatever is given after the @ is used as a function and called with the function-being-defined as argument. This explains why the wrap function is returned from the decorator (it will be called with a reference to the function that is being defined), and also why the original function is returned from the wrap function (the result will be assigned to the function name).

Using a statement interceptor, you can catch the execution of statements and do some special magic on them.  In our case, let's define an interceptor to catch the execution of a statement and log the result using the standard logging module. If you read the wrap function carefully, you probably noted that it uses a closure to access the value of orig when the decorator was called, not the value it happen to have when the wrap function is executed. This feature is very useful since a closure can also be used to get access to the original execute function and call it from within the new function.  So, to intercept an execute call and log information about the statement using the logging module, you could use code like this:


from mysql.connector import MySQLCursor
original_execute = MySQLCursor.execute
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
    if params is not None:
        stmt = operation % self._process_params(params)
    else:
        stmt = operation
    result = original_execute(self, operation, params)
    logging.debug("Executed '%s', rowcount: %d", stmt, self.rowcount)
    logging.debug("Columns: %s", ', '. join(c[0] for c in self.description))
    return result


Now with this, you could implement your own caching layer to, for example, do a memcached lookup before sending the statement to the server for execution. I leave this as an exercises to the reader, or maybe I'll show you in a later post. &#38;smiley;

Implementing a lifecycle interceptor is similar, only that you replace, for example, the commit or rollback calls. However, implementing an exception interceptor is not obvious.  Catching the exception is straightforward and can be done using the intercept decorator:


original_init = ProgrammingError.__init__
@intercept(ProgrammingError.__init__)
def catch_error(self, msg, errno):
    logging.debug("This statement didn't work: '%s', errno: %d", msg, errno)
    original_init(self, msg, errno=errno)


However, in order to do something more interesting, such as asking for some additional information from the database, it is necessary to either get hold of the cursor that was used to execute the query, or at least the connection. It is possible to dig through the interpreter stack, or try to override one of the internal methods that Connector/Python uses, but since that is very dependent on the implementation, I will not present that in this post.  It would be good if the cursor is passed down to the exception constructor, but this requires some changes to the connector code.

Even though I have been programming in dynamic languages for decades (literally) it always amaze me how easy it is to accomplish things in these languages. If you are interested in playing around with this code, you can always fetch Connector/Python on Launchpad and try out the examples above. Some links and other assorted references related to this post are:


  Connector/Python is found at launchpad.net/myconnpy
  Geert has a number of excellent posts on Connector/Python under geert.vanderkelen.org. Also, as you might already know, he is now working with developing Connector/Python and he's always interested in comments and suggestions. :)
  Todd's Blog mysqlblog.fivefarmers.com is always interesting to read, and these articles on interceptors are the ones I read
  
    Lifecycle Interceptors
    Statement Interceptors
    Exception Interceptors]]></description>
			<content:encoded><![CDATA[I recently found Todd's <a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/">posts</a> <a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/">on</a> <a href="http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%E2%80%93-exception-interceptors/">interceptors</a> which allow callbacks (called <em>interceptors</em>) to be registered with the connector so that you can intercept a statement execution, commit, or any of the many extension points supported by Connector/Java.  This is a language feature that allow you to implement a number of new features without having to change the application code such as load-balancing policies, profiling queries or transactions, or debugging an application.<p>

Since Python is a dynamic language, it is easy to add interceptors to <em>any</em> method in Connector/Python, without having to extend the connector with specific code. This is something that is possible in dynamic languages such as Python, Perl, JavaScript, and even some lesser known languages such as Lua and Self. In this post, I will describe how and also give an introduction to some of the (in my view) more powerful features of Python.<p>

In order to create an interceptor, you need to be able to do these things:

<ul>
  <li>Catch an existing method in a class and replace it with a new one.</li>
  <li>Call the original function, if necessary.</li>
  <li>For extra points: catch an existing method in an <em>object</em> and replace a new one.</li>
</ul>

You will in this post see how all three of these problems are solved in Python. You will see and use <em>decorators</em> to be able to define methods in existing classes and object, and closures to be able to call the original version of the methods.  By picking this approach, it will not be necessary to change the implementation: in fact, you can use this code to replace <em>any</em> method in <em>any</em> class, not only in Connector/Python.<p>

<table border="" width="">
<caption>Table 1. Attributes for methods</caption>
<TR>
  <TH></TH>
  <TH colspan="2">Method Instance</TH>
</TR>
<TR>
  <TH>Name</TH>
  <TH>Unbound</TH>
  <TH>Bound</TH></TR>
<TR>
  <TD><code>__name__</code></TD>
  <TD align="center" colspan="2">Name of Method</TD>
</TR>
<TR>
  <TD><code>im_func</code></TD>
  <TD align="center" colspan="2">"Inner" function of the method</TD>
</TR>
<TR>
  <TD><code>im_self</code></TD>
  <TD><code>None</code></TD>
  <TD align="center">Class instance for the method</TD>
</TR>
<TR>
  <TD><code>im_class</code></TD>
  <TD align="center" colspan="2">Class that the method belongs to</TD>
</TR>
</table>

In addition to being able to replace methods in the class, we would also like to be able to replace methods in instances of a class ("objects" in the traditional sense). This is useful to create specialized objects, for example for tracking particular cases where a method is used.<p>

In order to understand how the replacement works, you should understand that in Python (and the dynamic languages mentioned above), all objects can have attributes, including classes, functions, and a bunch of other esoteric constructions. Each type of object has a set of pre-defined attributes with well-defined meaning. For classes (and class instances), methods are stored as attributes of the class (or class instance) and can therefore be replaced with other methods that you build dynamically. However, it requires some tinkering to take an existing "normal" function definition and "imbue" it with whatever "tincture" that makes it behave as a method of the class or class instance.<p>

Depending on where the method comes from, it can be either <em>unbound</em> and <em>bound</em>. Unbound methods are roughly equivalent to member function pointers in C++: they reference a function, but not the instance. In contrast, bound methods have an instance tied to it, so when you call them, they already know what instance they belong to and will use it. Methods have a set of attributes, of which the four in Table&nbsp;1 interests us.  If a method is fetched from a class (to be precise, from a class object), it will be unbound and <code>im_self</code> will be <code>None</code>. If the method is fetched from a class <em>instance</em>, it will be bound and <code>im_self</code> will be set to the instance it belongs to. These attributes are all the "tincture" you need make our own instance methods.

The code for doing the replacement described above is simply:

<pre>
<code>import</code> functools, types

<code>def</code> replace_method(orig, func)
    functools.update_wrapper(func, orig.im_func)
    new = types.MethodType(func, orig.im_self, orig.im_class)
    obj = orig.im_self or orig.im_class
    setattr(obj, orig.__name__, new)
</pre>

The function uses two standard modules to make the job simpler, but the steps are:
<ol>
  <li>Copy the meta-information from the original method function to the new function using <code>update_wrapper</code>. This copies the name, module information, and documentation from the original method function to make it look like the original method.</li>
  <li>Create a new method instance from the method information of the original method using the constructor <code>MethodType</code>, but replace the "inner" function with the new function.</li>
  <li>Install the new instance method in the class or instance by replacing the attribute denoting the original method with the new method.  Depending on whether the function is given a bound or unbound instance, either the method in the class or in the instance is replaced.</li>
</ol>

Using this function you can now replace a method in a class like this:

<pre>
<code>from</code> mysql.connector <code>import</code> MySQLCursor

<code>def</code> my_execute(self, operation, params=None):
  ...

replace_method(MySQLCursor.execute, my_execute)
</pre>

This is already pretty useful, but note that you can also replace only a specific instance as well by using <code>replace_method(cursor.execute, my_execute)</code>. It was not necessary to change anything inside Connector/Python to intercept a method there, so you can actually apply this to any method in any of the classes in Connector/Python that you already have available.  In order to make it even easier to use you'll see how to define a <em>decorator</em> that will install the function in the correct place at the same time as it is defined. The code for defining a decorator and an example usage is:

<pre>
<code>import</code> functools, types
<code>from</code> mysql.connector <code>import</code> MySQLCursor

<code>def</code> intercept(orig):
    <code>def</code> wrap(func):
        functools.update_wrapper(func, orig.im_func)
        meth = types.MethodType(func, orig.im_self, orig.im_class)
        obj = orig.im_self or orig.im_class
        setattr(obj, orig.__name__, meth)
        return func
    return wrap

<span># Define a function using the decorator</span>
@intercept(MySQLCursor.execute)
<code>def</code> my_execute(self, operation, params=None):
  ...
</pre>

The <code>@intercept</code> line before the definition of <code>my_execute</code> is where the new descriptor is used. The syntax is a shorthand that can be used to do some things with the function when defining it. It behaves as if the following code had been executed:

<pre>
<code>def</code> <var>temporary</var>(self, operation, params=None):
  ...
my_execute = intercept(MySQLCursor.execute)(<var>temporary</var>)
</pre>

As you can see here, whatever is given after the <code>@</code> is used as a function and called with the function-being-defined as argument. This explains why the <code>wrap</code> function is returned from the decorator (it will be called with a reference to the function that is being defined), and also why the original function is returned from the <code>wrap</code> function (the result will be assigned to the function name).<p>

Using a statement interceptor, you can catch the execution of statements and do some special magic on them.  In our case, let's define an interceptor to catch the execution of a statement and log the result using the standard <a href="http://docs.python.org/library/logging.html"><code>logging</code></a> module. If you read the <code>wrap</code> function carefully, you probably noted that it uses a <dfn>closure</dfn> to access the value of <var>orig</var> when the decorator was <em>called</em>, not the value it happen to have when the <>wrap</code> function is executed. This feature is very useful since a closure can also be used to get access to the original <code>execute</code> function and call it from within the new function.  So, to intercept an execute call and log information about the statement using the <a href="http://docs.python.org/library/logging.html"><code>logging</code></a> module, you could use code like this:

<pre>
from mysql.connector import MySQLCursor
original_execute = MySQLCursor.execute
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
    if params is not None:
        stmt = operation % self._process_params(params)
    else:
        stmt = operation
    result = original_execute(self, operation, params)
    logging.debug("Executed '%s', rowcount: %d", stmt, self.rowcount)
    logging.debug("Columns: %s", ', '. join(c[0] for c in self.description))
    return result
</pre>

Now with this, you could implement your own caching layer to, for example, do a memcached lookup before sending the statement to the server for execution. I leave this as an exercises to the reader, or maybe I'll show you in a later post. &smiley;

Implementing a lifecycle interceptor is similar, only that you replace, for example, the commit or rollback calls. However, implementing an exception interceptor is not obvious.  Catching the exception is straightforward and can be done using the <code>intercept</code> decorator:

<pre>
original_init = ProgrammingError.__init__
@intercept(ProgrammingError.__init__)
def catch_error(self, msg, errno):
    logging.debug("This statement didn't work: '%s', errno: %d", msg, errno)
    original_init(self, msg, errno=errno)
</pre>

However, in order to do something more interesting, such as asking for some additional information from the database, it is necessary to either get hold of the cursor that was used to execute the query, or at least the connection. It is possible to dig through the interpreter stack, or try to override one of the internal methods that Connector/Python uses, but since that is very dependent on the implementation, I will not present that in this post.  It would be good if the cursor is passed down to the exception constructor, but this requires some changes to the connector code.<p>

Even though I have been programming in dynamic languages for decades (literally) it always amaze me how easy it is to accomplish things in these languages. If you are interested in playing around with this code, you can always fetch Connector/Python on Launchpad and try out the examples above. Some links and other assorted references related to this post are:

<ul>
  <li>Connector/Python is found at <a href="https://launchpad.net/myconnpy">launchpad.net/myconnpy</a></li>
  <li>Geert has a number of excellent posts on Connector/Python under <a href="http://geert.vanderkelen.org/">geert.vanderkelen.org</a>. Also, <a href="http://geert.vanderkelen.org/post/817">as you might already know</a>, he is now working with developing Connector/Python and he's always interested in comments and suggestions. :)
  <li>Todd's Blog <a href="http://mysqlblog.fivefarmers.com/">mysqlblog.fivefarmers.com</a> is always interesting to read, and these articles on interceptors are the ones I read
  <ul>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/">Lifecycle Interceptors</a>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/">Statement Interceptors</a>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%E2%80%93-exception-interceptors/">Exception Interceptors</a>
  </ul>
</ul><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/23496029-8853718009688026024?l=mysqlmusings.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=31777&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=31777&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2012/01/23/mysql-python-meta-programming-and-interceptors/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL: Python, Meta-Programming, and Interceptors</title>
		<link>http://mysqlmusings.blogspot.com/2012/01/mysql-python-meta-programming-and.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-python-meta-programming-and-interceptors-2</link>
		<comments>http://mysqlmusings.blogspot.com/2012/01/mysql-python-meta-programming-and.html#comments</comments>
		<pubDate>Mon, 23 Jan 2012 20:55:00 +0000</pubDate>
		<dc:creator>Mats Kindahl</dc:creator>
				<category><![CDATA[connector]]></category>
		<category><![CDATA[interceptor]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://planetmysql.ru/?guid=13e6b696138aee4a31ea45b7f36cdff1</guid>
		<description><![CDATA[I recently found Todd's posts on interceptors which allow callbacks (called interceptors) to be registered with the connector so that you can intercept a statement execution, commit, or any of the many extension points supported by Connector/Java.  This is a language feature that allow you to implement a number of new features without having to change the application code such as load-balancing policies, profiling queries or transactions, or debugging an application.

Since Python is a dynamic language, it is easy to add interceptors to any method in Connector/Python, without having to extend the connector with specific code. This is something that is possible in dynamic languages such as Python, Perl, JavaScript, and even some lesser known languages such as Lua and Self. In this post, I will describe how and also give an introduction to some of the (in my view) more powerful features of Python.

In order to create an interceptor, you need to be able to do these things:


  Catch an existing method in a class and replace it with a new one.
  Call the original function, if necessary.
  For extra points: catch an existing method in an object and replace a new one.


You will in this post see how all three of these problems are solved in Python. You will see and use decorators to be able to define methods in existing classes and object, and closures to be able to call the original version of the methods.  By picking this approach, it will not be necessary to change the implementation: in fact, you can use this code to replace any method in any class, not only in Connector/Python.


Table 1. Attributes for methods

  
  Method Instance


  Name
  Unbound
  Bound

  __name__
  Name of Method


  im_func
  "Inner" function of the method


  im_self
  None
  Class instance for the method


  im_class
  Class that the method belongs to



In addition to being able to replace methods in the class, we would also like to be able to replace methods in instances of a class ("objects" in the traditional sense). This is useful to create specialized objects, for example for tracking particular cases where a method is used.

In order to understand how the replacement works, you should understand that in Python (and the dynamic languages mentioned above), all objects can have attributes, including classes, functions, and a bunch of other esoteric constructions. Each type of object has a set of pre-defined attributes with well-defined meaning. For classes (and class instances), methods are stored as attributes of the class (or class instance) and can therefore be replaced with other methods that you build dynamically. However, it requires some tinkering to take an existing "normal" function definition and "imbue" it with whatever "tincture" that makes it behave as a method of the class or class instance.

Depending on where the method comes from, it can be either unbound and bound. Unbound methods are roughly equivalent to member function pointers in C++: they reference a function, but not the instance. In contrast, bound methods have an instance tied to it, so when you call them, they already know what instance they belong to and will use it. Methods have a set of attributes, of which the four in Table&#160;1 interests us.  If a method is fetched from a class (to be precise, from a class object), it will be unbound and im_self will be None. If the method is fetched from a class instance, it will be bound and im_self will be set to the instance it belongs to. These attributes are all the "tincture" you need make our own instance methods.

The code for doing the replacement described above is simply:


import functools, types

def replace_method(orig, func)
    functools.update_wrapper(func, orig.im_func)
    new = types.MethodType(func, orig.im_self, orig.im_class)
    obj = orig.im_self or orig.im_class
    setattr(obj, orig.__name__, new)


The function uses two standard modules to make the job simpler, but the steps are:

  Copy the meta-information from the original method function to the new function using update_wrapper. This copies the name, module information, and documentation from the original method function to make it look like the original method.
  Create a new method instance from the method information of the original method using the constructor MethodType, but replace the "inner" function with the new function.
  Install the new instance method in the class or instance by replacing the attribute denoting the original method with the new method.  Depending on whether the function is given a bound or unbound instance, either the method in the class or in the instance is replaced.


Using this function you can now replace a method in a class like this:


from mysql.connector import MySQLCursor

def my_execute(self, operation, params=None):
  ...

replace_method(MySQLCursor.execute, my_execute)


This is already pretty useful, but note that you can also replace only a specific instance as well by using replace_method(cursor.execute, my_execute). It was not necessary to change anything inside Connector/Python to intercept a method there, so you can actually apply this to any method in any of the classes in Connector/Python that you already have available.  In order to make it even easier to use you'll see how to define a decorator that will install the function in the correct place at the same time as it is defined. The code for defining a decorator and an example usage is:


import functools, types
from mysql.connector import MySQLCursor

def intercept(orig):
    def wrap(func):
        functools.update_wrapper(func, orig.im_func)
        meth = types.MethodType(func, orig.im_self, orig.im_class)
        obj = orig.im_self or orig.im_class
        setattr(obj, orig.__name__, meth)
        return func
    return wrap

# Define a function using the decorator
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
  ...


The @intercept line before the definition of my_execute is where the new descriptor is used. The syntax is a shorthand that can be used to do some things with the function when defining it. It behaves as if the following code had been executed:


def temporary(self, operation, params=None):
  ...
my_execute = intercept(MySQLCursor.execute)(temporary)


As you can see here, whatever is given after the @ is used as a function and called with the function-being-defined as argument. This explains why the wrap function is returned from the decorator (it will be called with a reference to the function that is being defined), and also why the original function is returned from the wrap function (the result will be assigned to the function name).

Using a statement interceptor, you can catch the execution of statements and do some special magic on them.  In our case, let's define an interceptor to catch the execution of a statement and log the result using the standard logging module. If you read the wrap function carefully, you probably noted that it uses a closure to access the value of orig when the decorator was called, not the value it happen to have when the wrap function is executed. This feature is very useful since a closure can also be used to get access to the original execute function and call it from within the new function.  So, to intercept an execute call and log information about the statement using the logging module, you could use code like this:


from mysql.connector import MySQLCursor
original_execute = MySQLCursor.execute
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
    if params is not None:
        stmt = operation % self._process_params(params)
    else:
        stmt = operation
    result = original_execute(self, operation, params)
    logging.debug("Executed '%s', rowcount: %d", stmt, self.rowcount)
    logging.debug("Columns: %s", ', '. join(c[0] for c in self.description))
    return result


Now with this, you could implement your own caching layer to, for example, do a memcached lookup before sending the statement to the server for execution. I leave this as an exercises to the reader, or maybe I'll show you in a later post. &#38;smiley;

Implementing a lifecycle interceptor is similar, only that you replace, for example, the commit or rollback calls. However, implementing an exception interceptor is not obvious.  Catching the exception is straightforward and can be done using the intercept decorator:


original_init = ProgrammingError.__init__
@intercept(ProgrammingError.__init__)
def catch_error(self, msg, errno):
    logging.debug("This statement didn't work: '%s', errno: %d", msg, errno)
    original_init(self, msg, errno=errno)


However, in order to do something more interesting, such as asking for some additional information from the database, it is necessary to either get hold of the cursor that was used to execute the query, or at least the connection. It is possible to dig through the interpreter stack, or try to override one of the internal methods that Connector/Python uses, but since that is very dependent on the implementation, I will not present that in this post.  It would be good if the cursor is passed down to the exception constructor, but this requires some changes to the connector code.

Even though I have been programming in dynamic languages for decades (literally) it always amaze me how easy it is to accomplish things in these languages. If you are interested in playing around with this code, you can always fetch Connector/Python on Launchpad and try out the examples above. Some links and other assorted references related to this post are:


  Connector/Python is found at launchpad.net/myconnpy
  Geert has a number of excellent posts on Connector/Python under geert.vanderkelen.org. Also, as you might already know, he is now working with developing Connector/Python and he's always interested in comments and suggestions. :)
  Todd's Blog mysqlblog.fivefarmers.com is always interesting to read, and these articles on interceptors are the ones I read
  
    Lifecycle Interceptors
    Statement Interceptors
    Exception Interceptors]]></description>
			<content:encoded><![CDATA[I recently found Todd's <a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/">posts</a> <a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/">on</a> <a href="http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%E2%80%93-exception-interceptors/">interceptors</a> which allow callbacks (called <em>interceptors</em>) to be registered with the connector so that you can intercept a statement execution, commit, or any of the many extension points supported by Connector/Java.  This is a language feature that allow you to implement a number of new features without having to change the application code such as load-balancing policies, profiling queries or transactions, or debugging an application.<p>

Since Python is a dynamic language, it is easy to add interceptors to <em>any</em> method in Connector/Python, without having to extend the connector with specific code. This is something that is possible in dynamic languages such as Python, Perl, JavaScript, and even some lesser known languages such as Lua and Self. In this post, I will describe how and also give an introduction to some of the (in my view) more powerful features of Python.<p>

In order to create an interceptor, you need to be able to do these things:

<ul>
  <li>Catch an existing method in a class and replace it with a new one.</li>
  <li>Call the original function, if necessary.</li>
  <li>For extra points: catch an existing method in an <em>object</em> and replace a new one.</li>
</ul>

You will in this post see how all three of these problems are solved in Python. You will see and use <em>decorators</em> to be able to define methods in existing classes and object, and closures to be able to call the original version of the methods.  By picking this approach, it will not be necessary to change the implementation: in fact, you can use this code to replace <em>any</em> method in <em>any</em> class, not only in Connector/Python.<p>

<table border="" width="">
<caption>Table 1. Attributes for methods</caption>
<TR>
  <TH></TH>
  <TH colspan="2">Method Instance</TH>
</TR>
<TR>
  <TH>Name</TH>
  <TH>Unbound</TH>
  <TH>Bound</TH></TR>
<TR>
  <TD><code>__name__</code></TD>
  <TD align="center" colspan="2">Name of Method</TD>
</TR>
<TR>
  <TD><code>im_func</code></TD>
  <TD align="center" colspan="2">"Inner" function of the method</TD>
</TR>
<TR>
  <TD><code>im_self</code></TD>
  <TD><code>None</code></TD>
  <TD align="center">Class instance for the method</TD>
</TR>
<TR>
  <TD><code>im_class</code></TD>
  <TD align="center" colspan="2">Class that the method belongs to</TD>
</TR>
</table>

In addition to being able to replace methods in the class, we would also like to be able to replace methods in instances of a class ("objects" in the traditional sense). This is useful to create specialized objects, for example for tracking particular cases where a method is used.<p>

In order to understand how the replacement works, you should understand that in Python (and the dynamic languages mentioned above), all objects can have attributes, including classes, functions, and a bunch of other esoteric constructions. Each type of object has a set of pre-defined attributes with well-defined meaning. For classes (and class instances), methods are stored as attributes of the class (or class instance) and can therefore be replaced with other methods that you build dynamically. However, it requires some tinkering to take an existing "normal" function definition and "imbue" it with whatever "tincture" that makes it behave as a method of the class or class instance.<p>

Depending on where the method comes from, it can be either <em>unbound</em> and <em>bound</em>. Unbound methods are roughly equivalent to member function pointers in C++: they reference a function, but not the instance. In contrast, bound methods have an instance tied to it, so when you call them, they already know what instance they belong to and will use it. Methods have a set of attributes, of which the four in Table&nbsp;1 interests us.  If a method is fetched from a class (to be precise, from a class object), it will be unbound and <code>im_self</code> will be <code>None</code>. If the method is fetched from a class <em>instance</em>, it will be bound and <code>im_self</code> will be set to the instance it belongs to. These attributes are all the "tincture" you need make our own instance methods.

The code for doing the replacement described above is simply:

<pre>
<code>import</code> functools, types

<code>def</code> replace_method(orig, func)
    functools.update_wrapper(func, orig.im_func)
    new = types.MethodType(func, orig.im_self, orig.im_class)
    obj = orig.im_self or orig.im_class
    setattr(obj, orig.__name__, new)
</pre>

The function uses two standard modules to make the job simpler, but the steps are:
<ol>
  <li>Copy the meta-information from the original method function to the new function using <code>update_wrapper</code>. This copies the name, module information, and documentation from the original method function to make it look like the original method.</li>
  <li>Create a new method instance from the method information of the original method using the constructor <code>MethodType</code>, but replace the "inner" function with the new function.</li>
  <li>Install the new instance method in the class or instance by replacing the attribute denoting the original method with the new method.  Depending on whether the function is given a bound or unbound instance, either the method in the class or in the instance is replaced.</li>
</ol>

Using this function you can now replace a method in a class like this:

<pre>
<code>from</code> mysql.connector <code>import</code> MySQLCursor

<code>def</code> my_execute(self, operation, params=None):
  ...

replace_method(MySQLCursor.execute, my_execute)
</pre>

This is already pretty useful, but note that you can also replace only a specific instance as well by using <code>replace_method(cursor.execute, my_execute)</code>. It was not necessary to change anything inside Connector/Python to intercept a method there, so you can actually apply this to any method in any of the classes in Connector/Python that you already have available.  In order to make it even easier to use you'll see how to define a <em>decorator</em> that will install the function in the correct place at the same time as it is defined. The code for defining a decorator and an example usage is:

<pre>
<code>import</code> functools, types
<code>from</code> mysql.connector <code>import</code> MySQLCursor

<code>def</code> intercept(orig):
    <code>def</code> wrap(func):
        functools.update_wrapper(func, orig.im_func)
        meth = types.MethodType(func, orig.im_self, orig.im_class)
        obj = orig.im_self or orig.im_class
        setattr(obj, orig.__name__, meth)
        return func
    return wrap

<span># Define a function using the decorator</span>
@intercept(MySQLCursor.execute)
<code>def</code> my_execute(self, operation, params=None):
  ...
</pre>

The <code>@intercept</code> line before the definition of <code>my_execute</code> is where the new descriptor is used. The syntax is a shorthand that can be used to do some things with the function when defining it. It behaves as if the following code had been executed:

<pre>
<code>def</code> <var>temporary</var>(self, operation, params=None):
  ...
my_execute = intercept(MySQLCursor.execute)(<var>temporary</var>)
</pre>

As you can see here, whatever is given after the <code>@</code> is used as a function and called with the function-being-defined as argument. This explains why the <code>wrap</code> function is returned from the decorator (it will be called with a reference to the function that is being defined), and also why the original function is returned from the <code>wrap</code> function (the result will be assigned to the function name).<p>

Using a statement interceptor, you can catch the execution of statements and do some special magic on them.  In our case, let's define an interceptor to catch the execution of a statement and log the result using the standard <a href="http://docs.python.org/library/logging.html"><code>logging</code></a> module. If you read the <code>wrap</code> function carefully, you probably noted that it uses a <dfn>closure</dfn> to access the value of <var>orig</var> when the decorator was <em>called</em>, not the value it happen to have when the <>wrap</code> function is executed. This feature is very useful since a closure can also be used to get access to the original <code>execute</code> function and call it from within the new function.  So, to intercept an execute call and log information about the statement using the <a href="http://docs.python.org/library/logging.html"><code>logging</code></a> module, you could use code like this:

<pre>
from mysql.connector import MySQLCursor
original_execute = MySQLCursor.execute
@intercept(MySQLCursor.execute)
def my_execute(self, operation, params=None):
    if params is not None:
        stmt = operation % self._process_params(params)
    else:
        stmt = operation
    result = original_execute(self, operation, params)
    logging.debug("Executed '%s', rowcount: %d", stmt, self.rowcount)
    logging.debug("Columns: %s", ', '. join(c[0] for c in self.description))
    return result
</pre>

Now with this, you could implement your own caching layer to, for example, do a memcached lookup before sending the statement to the server for execution. I leave this as an exercises to the reader, or maybe I'll show you in a later post. &smiley;

Implementing a lifecycle interceptor is similar, only that you replace, for example, the commit or rollback calls. However, implementing an exception interceptor is not obvious.  Catching the exception is straightforward and can be done using the <code>intercept</code> decorator:

<pre>
original_init = ProgrammingError.__init__
@intercept(ProgrammingError.__init__)
def catch_error(self, msg, errno):
    logging.debug("This statement didn't work: '%s', errno: %d", msg, errno)
    original_init(self, msg, errno=errno)
</pre>

However, in order to do something more interesting, such as asking for some additional information from the database, it is necessary to either get hold of the cursor that was used to execute the query, or at least the connection. It is possible to dig through the interpreter stack, or try to override one of the internal methods that Connector/Python uses, but since that is very dependent on the implementation, I will not present that in this post.  It would be good if the cursor is passed down to the exception constructor, but this requires some changes to the connector code.<p>

Even though I have been programming in dynamic languages for decades (literally) it always amaze me how easy it is to accomplish things in these languages. If you are interested in playing around with this code, you can always fetch Connector/Python on Launchpad and try out the examples above. Some links and other assorted references related to this post are:

<ul>
  <li>Connector/Python is found at <a href="https://launchpad.net/myconnpy">launchpad.net/myconnpy</a></li>
  <li>Geert has a number of excellent posts on Connector/Python under <a href="http://geert.vanderkelen.org/">geert.vanderkelen.org</a>. Also, <a href="http://geert.vanderkelen.org/post/817">as you might already know</a>, he is now working with developing Connector/Python and he's always interested in comments and suggestions. :)
  <li>Todd's Blog <a href="http://mysqlblog.fivefarmers.com/">mysqlblog.fivefarmers.com</a> is always interesting to read, and these articles on interceptors are the ones I read
  <ul>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-lifecycle-interceptors/">Lifecycle Interceptors</a>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/10/17/connectorj-extension-points-statement-interceptors/">Statement Interceptors</a>
    <li><a href="http://mysqlblog.fivefarmers.com/2011/11/21/connectorj-extension-points-%E2%80%93-exception-interceptors/">Exception Interceptors</a>
  </ul>
</ul><div><img width="1" height="1" src="https://blogger.googleusercontent.com/tracker/23496029-8853718009688026024?l=mysqlmusings.blogspot.com" alt="" /></div><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=31777&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=31777&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2012/01/23/mysql-python-meta-programming-and-interceptors-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatic reconnect in MySQL Connector/Python?</title>
		<link>http://geert.vanderkelen.org/post/842/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=automatic-reconnect-in-mysql-connectorpython</link>
		<comments>http://geert.vanderkelen.org/post/842/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 16:22:38 +0000</pubDate>
		<dc:creator>Geert Vanderkelen</dc:creator>
				<category><![CDATA[myconnpy]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://geert.vanderkelen.org/?p=842</guid>
		<description><![CDATA[There have been some request to have some reconnect possibilities in Connector/Python. I&#8217;m wondering now whether there should be some automatic reconnect on certain errors within the database driver.
My personal feeling is to have no automatic reconnect within Connector/Python and the programmer has to come up with retrying transactions herself.
For example:

	cnx.disconnect() # For testing..
	tries = 2
	while tries &#62; 0:
		tries -= 1
		try:
			cursor.execute(&#34;INSERT INTO t1 (c1) VALUES ('ham')&#34;)
			cnx.commit()
		except mysql.connector.InterfaceError:
			if tries == 0:
				print &#34;Failed inserting data after retrying&#34;
				break
			else:
				print &#34;Reconnecting..&#34;
				cnx.reconnect()
		else:
			break

The above mimics how you would handle transactions and trying them reconnecting. I have ideas how to get this into Connector/Python, but it would not really fit PEP-249.
Would the above use case of reconnecting be enough?]]></description>
			<content:encoded><![CDATA[<p>There have been some request to have some reconnect possibilities in <a href="http://launchpad.net/myconnpy" >Connector/Python</a>. I&#8217;m wondering now whether there should be some automatic reconnect on certain errors within the database driver.</p>
<p>My personal feeling is to have no automatic reconnect within Connector/Python and the programmer has to come up with retrying transactions herself.</p>
<p>For example:</p>
<pre>
	cnx.disconnect() # For testing..
	tries = 2
	while tries &gt; 0:
		tries -= 1
		try:
			cursor.execute(&quot;INSERT INTO t1 (c1) VALUES ('ham')&quot;)
			cnx.commit()
		except mysql.connector.InterfaceError:
			if tries == 0:
				print &quot;Failed inserting data after retrying&quot;
				break
			else:
				print &quot;Reconnecting..&quot;
				cnx.reconnect()
		else:
			break
</pre>
<p>The above mimics how you would handle transactions and trying them reconnecting. I have ideas how to get this into Connector/Python, but it would not really fit <a href="http://www.python.org/dev/peps/pep-0249/" >PEP-249</a>.</p>
<p>Would the above use case of reconnecting be enough?</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=31333&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=31333&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2011/12/16/automatic-reconnect-in-mysql-connectorpython/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing MySQLdb on MacOS Lion</title>
		<link>http://www.rustyrazorblade.com/2011/11/installing-mysqldb-on-macos-lion/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=installing-mysqldb-on-macos-lion</link>
		<comments>http://www.rustyrazorblade.com/2011/11/installing-mysqldb-on-macos-lion/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 06:58:01 +0000</pubDate>
		<dc:creator>Jonathan Haddad</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.rustyrazorblade.com/?p=1555</guid>
		<description><![CDATA[I ran into an issue installing the MySQLdb module.  
&#62;&#62;&#62; import MySQLdb
/Library/Python/2.7/site-packages/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg/_mysql.py:3: UserWarning: Module _mysql was already imported from /Library/Python/2.7/site-packages/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg/_mysql.pyc, but /Users/jhaddad/Downloads/MySQL-python-1.2.3 is being added to sys.path
Traceback (most recent call last):
  File &#8220;&#8220;, line 1, in 
  File &#8220;MySQLdb/__init__.py&#8221;, line 19, in 
    import _mysql
  File &#8220;build/bdist.macosx-10.7-intel/egg/_mysql.py&#8221;, line 7, in 
  File &#8220;build/bdist.macosx-10.7-intel/egg/_mysql.py&#8221;, line 6, in __bootstrap__
ImportError: dlopen(/var/root/.python-eggs/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg-tmp/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib
  Referenced from: /var/root/.python-eggs/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg-tmp/_mysql.so
  Reason: image not found
I fixed it by doing the following:
sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib
sudo ln -s /usr/local/mysql/lib /usr/local/mysql/lib/mysql
I&#8217;m not sure if it matters, but I&#8217;ve got MySQL 5.5 installed.  
Found the answer here &#8211; but it wasn&#8217;t the top voted one.  If this is useful, vote Chris up.
http://stackoverflow.com/questions/4730787/python-import-mysqldb-error-mac-10-6]]></description>
			<content:encoded><![CDATA[<p>I ran into an issue installing the <a href="http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.3/" title="MySQLdb module" >MySQLdb module</a>.  </p>
<blockquote><p>>>> import MySQLdb<br />
/Library/Python/2.7/site-packages/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg/_mysql.py:3: UserWarning: Module _mysql was already imported from /Library/Python/2.7/site-packages/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg/_mysql.pyc, but /Users/jhaddad/Downloads/MySQL-python-1.2.3 is being added to sys.path<br />
Traceback (most recent call last):<br />
  File &#8220;<stdin>&#8220;, line 1, in <module><br />
  File &#8220;MySQLdb/__init__.py&#8221;, line 19, in <module><br />
    import _mysql<br />
  File &#8220;build/bdist.macosx-10.7-intel/egg/_mysql.py&#8221;, line 7, in <module><br />
  File &#8220;build/bdist.macosx-10.7-intel/egg/_mysql.py&#8221;, line 6, in __bootstrap__<br />
ImportError: dlopen(/var/root/.python-eggs/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg-tmp/_mysql.so, 2): Library not loaded: libmysqlclient.18.dylib<br />
  Referenced from: /var/root/.python-eggs/MySQL_python-1.2.3-py2.7-macosx-10.7-intel.egg-tmp/_mysql.so<br />
  Reason: image not found</p></blockquote>
<p>I fixed it by doing the following:</p>
<blockquote><p>sudo ln -s /usr/local/mysql/lib/libmysqlclient.18.dylib /usr/lib/libmysqlclient.18.dylib</p>
<p>sudo ln -s /usr/local/mysql/lib /usr/local/mysql/lib/mysql</p></blockquote>
<p>I&#8217;m not sure if it matters, but I&#8217;ve got MySQL 5.5 installed.  </p>
<p>Found the answer here &#8211; but it wasn&#8217;t the top voted one.  If this is useful, vote Chris up.</p>
<p><a href="http://stackoverflow.com/questions/4730787/python-import-mysqldb-error-mac-10-6" >http://stackoverflow.com/questions/4730787/python-import-mysqldb-error-mac-10-6</a></p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=30925&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=30925&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2011/11/10/installing-mysqldb-on-macos-lion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Connector/Python available through the Python Package Index</title>
		<link>http://geert.vanderkelen.org/post/825/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-connectorpython-available-through-the-python-package-index</link>
		<comments>http://geert.vanderkelen.org/post/825/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 11:33:58 +0000</pubDate>
		<dc:creator>Geert Vanderkelen</dc:creator>
				<category><![CDATA[myconnpy]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://geert.vanderkelen.org/?p=825</guid>
		<description><![CDATA[Today we&#8217;ve registered MySQL Connector/Python with the Python Package Index (PyPI). It makes installing your favorite connector even easier (provided you installed setuptools first):

shell&#62; easy_install mysql-connector

Please report problems either using Launchpad or MySQL Bugs website.]]></description>
			<content:encoded><![CDATA[<p>Today we&#8217;ve registered <a href="http://launchpad.net/myconnpy">MySQL Connector/Python</a> with the <a href="http://pypi.python.org/pypi/MySQL-Connector/">Python Package Index</a> (PyPI). It makes installing your favorite connector even easier (provided you installed <a href="http://pypi.python.org/pypi/setuptools">setuptools</a> first):</p>
<pre>
shell&gt; easy_install mysql-connector
</pre>
<p>Please report problems either using <a href="https://bugs.launchpad.net/myconnpy">Launchpad</a> or <a href="http://bugs.mysql.com">MySQL Bugs website</a>.</p><br/>PlanetMySQL Voting:
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=30583&vote=1&apivote=1">Vote UP</a> /
	 <a href="http://planet.mysql.com/entry/vote/?entry_id=30583&vote=-1&apivote=1">Vote DOWN</a>]]></content:encoded>
			<wfw:commentRss>http://planetmysql.ru/2011/11/03/mysql-connectorpython-available-through-the-python-package-index/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

