<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Ryan Robitaille</title>
	
	<link>http://ryrobes.com</link>
	<description>going against the grain without getting splinters</description>
	<lastBuildDate>Wed, 30 Dec 2009 23:44:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Ryrobes" /><feedburner:info uri="ryrobes" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>Ryrobes</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Get Clicky Android Widget = Awesomely Convenient</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/hYwKEa35Qgc/</link>
		<comments>http://ryrobes.com/random/get-clicky-android-widget-awesomely-convenient/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 08:28:29 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[Widgets]]></category>
		<category><![CDATA[clicky]]></category>
		<category><![CDATA[droid]]></category>
		<category><![CDATA[getclicky]]></category>
		<category><![CDATA[mororola]]></category>
		<category><![CDATA[verizon]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=191</guid>
		<description><![CDATA[If you&#8217;re like me (exactly maybe, as scary as that might be) and have a Motorola Droid, and use Clicky for awesome and simple web analytics &#8211; you&#8217;ll want this. 
Its only 1 dollar &#8211; which is the same as a double cheeseburger at McDonalds (if you local vendors participate &#8211; since we all know [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://ryrobes.com/wp-content/uploads/2009/12/android-widget.jpg" alt="android-widget" title="android-widget" width="350" height="623" class="alignleft size-full wp-image-193" />If you&#8217;re like me <em>(exactly maybe, as scary as that might be)</em> and have a <strong>Motorola Droid</strong>, and use <a href="http://getclicky.com/111541">Clicky</a> for <a href="http://getclicky.com/111541">awesome and simple web analytics</a> &#8211; you&#8217;ll want this. </p>
<p>Its only 1 dollar &#8211; which is the same as a double cheeseburger at McDonalds <em>(if you local vendors participate &#8211; since we all know that &#8220;participation may vary&#8221;)</em> if you want to make a dollar-for-dollar comparison&#8230;</p>
<p><img src="http://ryrobes.com/wp-content/uploads/2009/12/qrcode-clickywidget.png" alt="qrcode-clickywidget" title="qrcode-clickywidget" width="186" height="186" class="alignright size-full wp-image-201" /><br />
<br/><br/><br/><br/><br/><br/><br/><br/><br/></p>
<p>It uses the Clicky API to grab the unique visitors and actions from a given site that you are monitoring on a hourly basis <em>(ie &#8211; it get refreshed hourly)</em>, and show the data as a daily, hourly, weekly and monthly aggregate count &#8211; plus an extra click takes you right to the Android-optimized Clicky Report page.. Who can argue with that?</p>
<div style="clear:both;"></div>
<p>Enjoy. <br/><br />
Original developers <a href="http://bit.ly/6zo5Nl">post is here</a>, he also runs <a href="http://phillyconcerthub.com/">http://phillyconcerthub.com/</a>. </p>
<p><br/>Check it out.<br />
<br/><em>BTW, that screenshot was very much reduced. The DPI of the Droid is so sexy that it looks absolutely massive on most 72 DPI computer monitors&#8230; Take that, iPhone kids. ;)</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hYwKEa35Qgc:El01RUA0Efk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hYwKEa35Qgc:El01RUA0Efk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hYwKEa35Qgc:El01RUA0Efk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hYwKEa35Qgc:El01RUA0Efk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hYwKEa35Qgc:El01RUA0Efk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hYwKEa35Qgc:El01RUA0Efk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/hYwKEa35Qgc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/random/get-clicky-android-widget-awesomely-convenient/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://ryrobes.com/random/get-clicky-android-widget-awesomely-convenient/</feedburner:origLink></item>
		<item>
		<title>Using XLWT and Python to export an Oracle dataset to Excel (Python Simple ETL Part 2)</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/SsZ1xF2ogNA/</link>
		<comments>http://ryrobes.com/featured-articles/using-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 04:31:22 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Reporting]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[data transformation]]></category>
		<category><![CDATA[dts]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[excel export]]></category>
		<category><![CDATA[extract transform and load]]></category>
		<category><![CDATA[open-source]]></category>
		<category><![CDATA[overpriced dickheads]]></category>
		<category><![CDATA[pyExcelerator]]></category>
		<category><![CDATA[reporting services]]></category>
		<category><![CDATA[reports]]></category>
		<category><![CDATA[ryrobes]]></category>
		<category><![CDATA[xlwt]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=176</guid>
		<description><![CDATA[A few months ago, I showed how you can do simple back and forth ETL task with python scripts &#8211; this time I&#8217;m going to take it one step further and show how with an extra python module we can actually export data to a usable Excel format as well. I often use this method [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago, I showed how you can do simple back and forth ETL task with python scripts &#8211; this time I&#8217;m going to take it one step further and show how with an extra python module we can actually export data to a usable Excel format as well. I often use this method for automated data extracts <strong>AS WELL AS doing full blown Excel reports</strong> <em>(yes, that&#8217;s right &#8211; with formula calculations, formatting and everything &#8211; its pretty sweet &#8211; that&#8217;ll come later though)</em>.</p>
<blockquote><p>I always say that &#8220;ease of use&#8221; and &#8220;flexibility&#8221; are at opposite ends of the spectrum &#8211; when one goes up, the other goes down. WYSIWYG applications have their place (I suppose), I prefer coding by hand in a text editor anyday.</p></blockquote>
<p>Anyways, today we&#8217;re going to make a simple Excel data export with pythons xlwt module <em>(which is a more updated fork of the old pyExcelerator module)</em>. I&#8217;ll try and comment well so you can cut-n-paste to your hearts content. As well all know, there&#8217;s nothing better than Googling for a solution and finding one that is 90% what you need and being able to just hack that last 10% in &#8211; saves time and sanity. Some purists would argue that its wrong&#8230; maybe, but there is a time and place for everything.</p>
<p>Anyways, here we go &#8211; as always, you can go step-by-step <em>(like the Full House theme song)</em> with me through the code, or skip to the bottom and just download the whole file. Its small, but at least this saves you from having to do a ton of Ctrl-C and Ctrl-V&#8230;</p>
<p>Ok, Lets get <em>(motherfuckin&#8217;)</em> steppin&#8217;&#8230; <em>(pardon me &#8211; its a live Metallica reference, can&#8217;t help it, I&#8217;m a product of the 80s and 90s whether I like it or not)</em></p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># 12/7/2009 - Ryan Robitaille [ryrobes.com]</span><br />
<span style="color: #808080; font-style: italic;"># http://ryrobes.com/featured-articles/using-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2/</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> cx_Oracle, <span style="color: #dc143c;">time</span>, <span style="color: #dc143c;">string</span><br />
<span style="color: #ff7700;font-weight:bold;">from</span> xlwt <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span> &nbsp;<span style="color: #808080; font-style: italic;">#formerly &quot;pyExcelerator&quot;</span></div></div>
<p>Standard stuff &#8211; just loading some modules that we&#8217;re going to need. Time and String are part of the standard Python distriution <em>(I&#8217;m using 2.6 in this example)</em>, cx_Oracle I <a href="http://ryrobes.com/featured-articles/using-a-simple-python-script-for-end-to-end-data-transformation-and-etl-part-1/">already discussed HERE</a>, and xlwt can be found HERE (<a href="http://pypi.python.org/pypi/xlwt">http://pypi.python.org/pypi/xlwt</a>) grab the packages for your platform of choice and go nuts.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># set oracle login variables</span><br />
OraUid=<span style="color: #483d8b;">&quot;scott&quot;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#Oracle User &nbsp;</span><br />
OraPwd=<span style="color: #483d8b;">&quot;tiger&quot;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#Oracle password</span><br />
OraService=<span style="color: #483d8b;">&quot;TNS_EETFUK&quot;</span> &nbsp; &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#Oracle Service name From Tnsnames.ora file</span><br />
<br />
<span style="color: #808080; font-style: italic;"># do a timestamp for being able to track execution time (if you want)</span><br />
startscript = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;"># we will use this later</span><br />
&nbsp;<br />
db = cx_Oracle.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>OraUid + <span style="color: #483d8b;">&quot;/&quot;</span> + OraPwd + <span style="color: #483d8b;">&quot;@&quot;</span> + OraService<span style="color: black;">&#41;</span> &nbsp; &nbsp;<span style="color: #808080; font-style: italic;">#Connect to database</span><br />
dev_cursor_select = db.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;">#Allocate a cursor</span><br />
<br />
dev_cursor_select.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&quot;&quot;SELECT DBMS_RANDOM.STRING('P',40) field1, <br />
&nbsp; &nbsp; &nbsp; &nbsp; DBMS_RANDOM.STRING('X',30) field2, ROUND(DBMS_RANDOM.VALUE(1000, 9999)) field3, <br />
&nbsp; &nbsp; &nbsp; &nbsp; DBMS_RANDOM.STRING('A',20) field4 &nbsp;FROM DUAL CONNECT BY LEVEL&lt;=3000&quot;&quot;&quot;</span><span style="color: black;">&#41;</span><br />
<span style="color: #808080; font-style: italic;"># 3,000 rows of random garbage seems good</span><br />
<br />
result_set = dev_cursor_select.<span style="color: black;">fetchall</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>There is a bit more going on here, but nothing really complex &#8211; setting up our Oracle connection, timestamping the START of the script, creating our Oracle cursor, defining our SQL query (just some random Oracle generated nonsense for the sake of this demo using the awesome and under-used &#8216;DBMS_RANDOM&#8217; functions), and getting that result set into a python object.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;"># Start some Excel magic</span><br />
wb = Workbook<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
ws0 = wb.<span style="color: black;">add_sheet</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'My New Worksheet'</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Grey background for the header row</span><br />
BkgPat = Pattern<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
BkgPat.<span style="color: black;">pattern</span> = Pattern.<span style="color: black;">SOLID_PATTERN</span><br />
BkgPat.<span style="color: black;">pattern_fore_colour</span> = <span style="color: #ff4500;">22</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Bold Fonts for the header row</span><br />
font = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
font.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Calibri'</span><br />
font.<span style="color: black;">bold</span> = <span style="color: #008000;">True</span><br />
<br />
<span style="color: #808080; font-style: italic;"># Non-Bold fonts for the body</span><br />
font0 = Font<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
font0.<span style="color: black;">name</span> = <span style="color: #483d8b;">'Calibri'</span><br />
font0.<span style="color: black;">bold</span> = <span style="color: #008000;">False</span><br />
<br />
<span style="color: #808080; font-style: italic;"># style and write field labels</span><br />
style = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
style.<span style="color: black;">font</span> = font<br />
style.<span style="color: black;">pattern</span> = BkgPat<br />
<br />
style0 = XFStyle<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
style0.<span style="color: black;">font</span> = font0</div></div>
<p>Here we start some Excel formatting. Formatting is optional, but I figured that I&#8217;d throw in a little bit for some flavor. I can&#8217;t stand when older Excel uses that horrible &#8220;OCR A&#8221; font as the default. So what I&#8217;m doing is defining &#8220;styles&#8221; that can applied to each cell as we write data out to them. I&#8217;m using the same font throughout (in this case Calibri), but I&#8217;m making the header row bold and having a grey cell background. </p>
<p>Confused? Don&#8217;t worry &#8211; It will make a lot more sense in a moment.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">row_number=1&nbsp; &nbsp; <br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> row <span style="color: #ff7700;font-weight:bold;">in</span> result_set:<br />
&nbsp; &nbsp; column_num=0<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> row: <span style="color: #808080; font-style: italic;">#i.e. for each field in that row</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span>row_number,column_num,<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span>,style0<span style="color: black;">&#41;</span> &nbsp;<span style="color: #808080; font-style: italic;">#write excel cell from the cursor at row 1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; column_num=column_num+<span style="color: #ff4500;">1</span> &nbsp;<span style="color: #808080; font-style: italic;">#increment the column to get the next field</span><br />
<br />
&nbsp; &nbsp; row_number=row_number+<span style="color: #ff4500;">1</span> <span style="color: #808080; font-style: italic;">#increment the row number so the next row goes below it...</span></div></div>
<p>Here we are looping through the result set. I&#8217;m starting the rows at &#8220;row 1&#8243;, which is actually row number 2 in Excel &#8211; we need the space in row number 1 in order to put our header row at. Otherwise we would start the output on row_number 0.</p>
<p>For each row in out result set, we have to write out all the fields in their individual columns. It sounds like a lot of work, but Python makes it easy. Just remember to increment your column numbers out and then reset them to 0 (aka literal column 1) when you start the next row. </p>
<p>If we wanted to get a little more tricky and &#8220;automatically&#8221; set the column width too. That takes a bit of finesse though, since not all field string lengths are created equally&#8230;</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">col_width_dict = <span style="color: #008000;">dict</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;"># create a dictionary var</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">4</span><span style="color: black;">&#41;</span>: <span style="color: #808080; font-style: italic;"># fill it up with 0s first so Python doesn't complain</span><br />
&nbsp; &nbsp; col_width_dict<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span> = 0<br />
<br />
row_number=1<br />
<br />
<span style="color: #ff7700;font-weight:bold;">for</span> row <span style="color: #ff7700;font-weight:bold;">in</span> result_set:<br />
&nbsp; &nbsp; column_num=0<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> item <span style="color: #ff7700;font-weight:bold;">in</span> row:<br />
&nbsp; &nbsp; &nbsp; &nbsp; ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span>row_number,column_num,<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span>,style0<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># write the excel row from the cursor - starting at row 1 (literal row 2)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #66cc66;">&gt;</span> col_width_dict<span style="color: black;">&#91;</span>column_num<span style="color: black;">&#93;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># only redefine the column width if we need it to be bigger</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; col_width_dict<span style="color: black;">&#91;</span>column_num<span style="color: black;">&#93;</span> = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ws0.<span style="color: black;">col</span><span style="color: black;">&#40;</span>column_num<span style="color: black;">&#41;</span>.<span style="color: black;">width</span> = <span style="color: #008000;">len</span><span style="color: black;">&#40;</span><span style="color: #008000;">str</span><span style="color: black;">&#40;</span>item<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">*</span><span style="color: #ff4500;">256</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># set the width of the column depending on incoming string</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; column_num=column_num+<span style="color: #ff4500;">1</span><br />
<br />
&nbsp; &nbsp; row_number=row_number+<span style="color: #ff4500;">1</span></div></div>
<p>Still with me? Good. <em>(if not, let me know in the comments and I&#8217;ll try and clarify things more)</em>.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">0</span>,<span style="color: #483d8b;">'Field 1'</span>,style<span style="color: black;">&#41;</span><br />
ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">1</span>,<span style="color: #483d8b;">'Field 2'</span>,style<span style="color: black;">&#41;</span><br />
ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">2</span>,<span style="color: #483d8b;">'Field 3'</span>,style<span style="color: black;">&#41;</span><br />
ws0.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>,<span style="color: #ff4500;">3</span>,<span style="color: #483d8b;">'Field 4'</span>,style<span style="color: black;">&#41;</span><br />
<br />
wb.<span style="color: black;">save</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'sample_output.xls'</span><span style="color: black;">&#41;</span><br />
<br />
endscript = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
endtime = endscript - startscript<br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">'script run in '</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>endscript - startscript<span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' seconds or '</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>endscript - startscript<span style="color: black;">&#41;</span>/<span style="color: #ff4500;">60</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' minutes'</span></div></div>
<p>Here we are writing the header row (with our fancy &#8220;style&#8221; attribute), we are explicitly writing it on the first column (the one we skipped earlier when writing out the data).</p>
<p>Then we save our excel file as &#8217;sample_output.xls&#8217; or &#8216;angry_beavers.xls&#8217; or &#8216;chiminny_changa.xls&#8217;, whatever floats your boat. Just for shits and giggles, I&#8217;m taking the start timestamp and and the end timestamp and showing how long the script too to execute, but its pretty much useless in this case and olney serves to have some (not so) interesting output for me to look at.</p>
<p>Is anyone confused, angry, irate, excited? Let me know in the comments!</p>
<p>Here is the <a title="http://ryrobes.com/using-xlwt-and-python-to-export-to-excel.py" href="http://ryrobes.com/using-xlwt-and-python-to-export-to-excel.py">entire commented script file</a> for downloading. </p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=SsZ1xF2ogNA:SVtMjY0PNtc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=SsZ1xF2ogNA:SVtMjY0PNtc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=SsZ1xF2ogNA:SVtMjY0PNtc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=SsZ1xF2ogNA:SVtMjY0PNtc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=SsZ1xF2ogNA:SVtMjY0PNtc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=SsZ1xF2ogNA:SVtMjY0PNtc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/SsZ1xF2ogNA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/featured-articles/using-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://ryrobes.com/featured-articles/using-xlwt-and-python-to-export-an-oracle-dataset-to-excel-python-simple-etl-part-2/</feedburner:origLink></item>
		<item>
		<title>Cut-N-Paste Corner: Microsoft SQL Server 2000, 2005, 2008 Simple Loop Template</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/dz_ivccjey4/</link>
		<comments>http://ryrobes.com/geek/cut-n-paste-corner-microsoft-sql-server-2000-2005-2008-simple-loop-template/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 01:01:23 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Microsoft SQL Server]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[cursors]]></category>
		<category><![CDATA[Data Warehousing]]></category>
		<category><![CDATA[dts]]></category>
		<category><![CDATA[ETL]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[rambling]]></category>
		<category><![CDATA[simple]]></category>
		<category><![CDATA[snippets]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=157</guid>
		<description><![CDATA[I think that &#8216;data wrangling&#8217; takes a special kind of problem solving mentality. Keeping data current, cleaning it, merging it, aggregating it, and creating summary (or data warehouse) tables for reporting purposes&#8230; For MANY years I used Express installations of SQL Server 2000 as my ultimate data Swiss Army knife. It was like a secret [...]]]></description>
			<content:encoded><![CDATA[<p>I think that &#8216;data wrangling&#8217; takes a special kind of problem solving mentality. Keeping data current, cleaning it, merging it, aggregating it, and creating summary (or data warehouse) tables for reporting purposes&#8230; For MANY years I used Express installations of SQL Server 2000 as my ultimate data Swiss Army knife. It was like a secret weapon. You can crank out a couple of databases, make a DTS package, add some SQL flavor, ODBC connections to whatever you need &#8211; and viola &#8211; have a working and update-able consolidated data source in no time flat.</p>
<p>It never really mattered what kind of beast you were up against &#8211; Access, Paradox, Oracle, MySQL, Excel, delimited files, or just text files with shitty formatting. Say what you want about SQL Server 2000 and DTS &#8211; but it was hella flexible <em>(probably unmatched in ease and flexibility still to this day, IMHO)</em>.</p>
<p>Although I spend a good deal of time with Oracle these days &#8211; I have recently taken on some large migrations using SQL Server 2008, which pushed me to dig up my archaic library of SQL code I used to cut-n-paste back and forth in the 2000 days in order to get just-about-anythinhg done. I&#8217;m going to be posting some of the more useful and interesting ones</p>
<p>It may be simple, or it may be complicated &#8211; but when you&#8217;re searching for a hammer &#8211; the last thing you want is a bunch of meat tenderizers. Its damned close, but not exactly what you need. Today I&#8217;m posting a simple SQL Server cursor loop statement that you can add to your collection of templates.</p>
<blockquote><p><em><strong>Disclaimer:</strong></em> Now some of you might be asking: Isn&#8217;t this pretty elementary? Yes, but maybe not everyone reading this has your <strong>&#8220;l33t hax0r skillz&#8221;</strong>, ok there, Captain Ahab?</p></blockquote>
<p>Screw that noise. I&#8217;m all about creating specific solutions to specific problems &#8211; and nothing is more usable, extensible, and straight-up customizable than a simple T-SQL cursor loop. It doesn&#8217;t matter if youre updating rows on a separate table, doing a complicated INSERT INTO, doing some multi-variable lookups, or hell &#8211; maybe all of the above. Use your imagination. A good starting point prevents you from getting &#8220;code-blocked&#8221; and staring at a blank text editor or query screen as your jaws hangs open like a common mouth breather.</p>
<p>I write complicated ass SQL all day, and I open templates like this to modify all the time. I&#8217;ve got a whole library of them just for that purpose. I mean, c&#8217;mon lets get real, who actually sits down and writes stuff from scratch EVERY time? I&#8217;m all about the self-plagiarism, especially if it saves me time at the end of the day.</p>
<p>This example is supposed to be a simple as possible, while also being semi-plausible. Hypothetically, lets say you were building a summary table of all employees broken down by office, salary, department, etc. What we are doing is setting a True flag in a field on the summary table for the employee who has the highest salary for that particular office <em>(I know it sounds odd &#8211; but like I said, its hypothetical, this could just as easily be doing a top flag based on department, or number of sales, seniority, etc. &#8211; I just thought that using salary by office is an easily understood one)</em>.</p>
<p>Here is an explanation in English about what the example is doing &#8211; data-wise&#8230;</p>
<p>First, we grab all the individual Office Ids &#8211; then go one by one through each of the different offices ranking the employees by salary, taking the highest paid Employee ID and then updating that same tables &#8220;Top Salary in the Office&#8221; field for that particular employee.</p>
<div class="codecolorer-container sql vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">--Simple Cursor-based Loop for Microsoft SQL Server (2000+)</span><br />
<span style="color: #808080; font-style: italic;">--Ryan Robitaille (ryrobes.com) 12/1/2009</span><br />
<br />
<span style="color: #808080; font-style: italic;">--First define our return variable for the cursor and other misc vars</span><br />
DECLARE @top_paid_in_office_emp_id varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span> @office_id varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">15</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #808080; font-style: italic;">--here is the actual cursor select statement</span><br />
DECLARE all_offices_cursor CURSOR <span style="color: #993333; font-weight: bold;">FOR</span><br />
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #993333; font-weight: bold;">DISTINCT</span> office_id <span style="color: #993333; font-weight: bold;">FROM</span> coded_offices<br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> office_id<br />
<br />
<span style="color: #808080; font-style: italic;">--open that beast so we can use it</span><br />
OPEN all_offices_cursor<br />
<br />
<span style="color: #808080; font-style: italic;">--start iterating through the cursor result set</span><br />
FETCH NEXT <span style="color: #993333; font-weight: bold;">FROM</span> all_offices_cursor<br />
<span style="color: #993333; font-weight: bold;">INTO</span> @office_id<br />
<br />
<span style="color: #808080; font-style: italic;">--only pull in rows that we havent seen yet, else stop</span><br />
WHILE @@FETCH_STATUS <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span><br />
BEGIN<br />
<br />
<span style="color: #808080; font-style: italic;">--start actual looping statement using our cursor variables</span><br />
<span style="color: #993333; font-weight: bold;">SET</span> @top_paid_in_office_emp_id <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> top 1 employee_id<br />
<span style="color: #993333; font-weight: bold;">FROM</span> office_roster_summary<br />
<span style="color: #993333; font-weight: bold;">WHERE</span> office_id <span style="color: #66cc66;">=</span> @office_id<br />
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> salary <span style="color: #993333; font-weight: bold;">DESC</span><span style="color: #66cc66;">&#41;</span><br />
<br />
<span style="color: #993333; font-weight: bold;">UPDATE</span> office_roster_summary <span style="color: #993333; font-weight: bold;">SET</span> top_paid_flag <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'T'</span><br />
<span style="color: #993333; font-weight: bold;">WHERE</span> employee_id <span style="color: #66cc66;">=</span> @top_paid_in_office_emp_id<br />
<span style="color: #993333; font-weight: bold;">AND</span> office_id <span style="color: #66cc66;">=</span> @office_id<br />
<span style="color: #808080; font-style: italic;">--end looping statement</span><br />
<br />
FETCH NEXT <span style="color: #993333; font-weight: bold;">FROM</span> all_offices_cursor<br />
<span style="color: #993333; font-weight: bold;">INTO</span> @office_id<br />
<span style="color: #808080; font-style: italic;">--grab the next var(s) from the cursor and repeat, baby!</span><br />
END<br />
<br />
CLOSE all_offices_cursor<br />
DEALLOCATE all_offices_cursor<br />
<br />
<span style="color: #808080; font-style: italic;">--Close the cursor, and deallocate it for good housekeeping sake...</span><br />
<span style="color: #808080; font-style: italic;">--Booya</span></div></div>
<p>Depending on your data &#8211; when building a summary table (or Data Warehouse Fact table, or Analysis Services Cube for that matter) these types of &#8220;flag&#8221; fields often make reporting on such items much easier.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=dz_ivccjey4:DMu01i03h80:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=dz_ivccjey4:DMu01i03h80:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=dz_ivccjey4:DMu01i03h80:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=dz_ivccjey4:DMu01i03h80:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=dz_ivccjey4:DMu01i03h80:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=dz_ivccjey4:DMu01i03h80:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/dz_ivccjey4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/geek/cut-n-paste-corner-microsoft-sql-server-2000-2005-2008-simple-loop-template/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/geek/cut-n-paste-corner-microsoft-sql-server-2000-2005-2008-simple-loop-template/</feedburner:origLink></item>
		<item>
		<title>You can pet my Goat. Just wash your hands first, please.</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/mDJnyJ2o9-k/</link>
		<comments>http://ryrobes.com/random/you-can-pet-my-goat-just-wash-your-hands-first-please/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 05:09:38 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Irreverence]]></category>
		<category><![CDATA[Ramble]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[cartoons]]></category>
		<category><![CDATA[comedy]]></category>
		<category><![CDATA[goats]]></category>
		<category><![CDATA[tin cans]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=149</guid>
		<description><![CDATA[I tried to feed a goat a tin can once.
He wouldn&#8217;t eat it.
Cartoons have steered me wrong once again.
Besides&#8230; the supervising Goat master scolded me before the Goat had a chance to fully understand the situation he was being out in. Maybe that particular Goat had diabetes and wasn&#8217;t allowed to eat my tuna can. [...]]]></description>
			<content:encoded><![CDATA[<p>I tried to feed a goat a tin can once.<br />
He <em>wouldn&#8217;t</em> eat it.</p>
<h3>Cartoons have steered me wrong once again.</h3>
<p>Besides&#8230; the supervising Goat master scolded me before the Goat had a chance to fully understand the situation he was being out in. Maybe that particular Goat had diabetes and wasn&#8217;t allowed to eat my tuna can. I&#8217;ll never be sure. I generally don&#8217;t eat tin cans, but if I did, it would have been delicious, I can tell.</p>
<p>I have to say, honestly, If there is anything better than a goat, its a goat that you can walk up to and pet on the back of the head. Actually, its a goat that you can walk up to, pet on the back of the head and then proceed to feed garbage to &#8211; while obviously being protected by a sturdy &#8216;Goat Barrier&#8217;, because I don&#8217;t know how the goat feels about killing me. Hopefully, he&#8217;s against it&#8230; much like I am.</p>
<p><strong>Imagine that. Killed by a goat. There&#8217;d be no evidence left.</strong></p>
<p>Not to mention that fact the prosecutors wouldn&#8217;t be able to get a single goat to take the stand in my defense. I think its a union thing, they can&#8217;t turn on their own. I wouldn&#8217;t rule out a Billygoat doing it, but they have much less credibility than Goats.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=mDJnyJ2o9-k:g6xjiYvx7ok:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=mDJnyJ2o9-k:g6xjiYvx7ok:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=mDJnyJ2o9-k:g6xjiYvx7ok:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=mDJnyJ2o9-k:g6xjiYvx7ok:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=mDJnyJ2o9-k:g6xjiYvx7ok:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=mDJnyJ2o9-k:g6xjiYvx7ok:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/mDJnyJ2o9-k" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/random/you-can-pet-my-goat-just-wash-your-hands-first-please/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/random/you-can-pet-my-goat-just-wash-your-hands-first-please/</feedburner:origLink></item>
		<item>
		<title>Using a simple Python script for End-to-End Data Transformation and ETL (Part 1)</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/Bky8YbcF0o0/</link>
		<comments>http://ryrobes.com/featured-articles/using-a-simple-python-script-for-end-to-end-data-transformation-and-etl-part-1/#comments</comments>
		<pubDate>Thu, 30 Jul 2009 01:40:35 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[ETL]]></category>
		<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[consultants]]></category>
		<category><![CDATA[data transformation]]></category>
		<category><![CDATA[dts]]></category>
		<category><![CDATA[extract transform and load]]></category>
		<category><![CDATA[microsoft sql]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[overpriced dickheads]]></category>
		<category><![CDATA[proprietary shit]]></category>
		<category><![CDATA[ryrobes]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=91</guid>
		<description><![CDATA[In the Data Transformation Services (DTS) / Extract Transform and Load (ETL) world these days we&#8217;ve got a LOT of expensive ass products.  Some are good, some are marginal, and some are pieces of over-complicated (and poorly performing) java-based shit. But, hey, enough with the negativity &#8211; I digress, I just want to show [...]]]></description>
			<content:encoded><![CDATA[<p>In the Data Transformation Services (DTS) / Extract Transform and Load (ETL) world these days we&#8217;ve got a LOT of expensive ass products.  Some are good, some are marginal, and some are pieces of over-complicated (and poorly performing) java-based shit. But, hey, enough with the negativity &#8211; I digress, I just want to show you that its pretty easy to do the same types of data manipulations in pure easy-to-read python code. Why lock yourselves into an expensive proprietary ETL system that requires expensive consultants to maintain <em>(badly)</em>?</p>
<p>In this multi-part post I&#8217;m going to start with a simple data transport across data platforms (with minimal exception handling), and later mix in some fancier ETL functions and <em><strong>&#8220;robustness&#8221;</strong></em> (if that&#8217;s even a word &#8211; I know I&#8217;ve heard Cheese-Nip Sales guys use it before). I guarantee its a hell of a lot faster and more reliable than any of the commercial products out there (I know, because I&#8217;ve use them all).</p>
<h3>In my not-so-humble opinion, you should NEVER trade point-and-click usability and prettiness for rock-solid reliability and flexibility.</h3>
<blockquote><p><strong>Note:</strong> I&#8217;m going to be doing this in a nice and easy step-by-step way &#8211; I&#8217;m not trying to insult anyone&#8217;s intelligence, but I find that when people gloss over things because <strong>&#8220;everyone knows XYZ&#8221;</strong>, it alienates people and makes shit downright confusing for others &#8211; so if you&#8217;re a python smarty pants and already know all this, just skip that section and go buy yourself a cup of green tea <em>(or whatever the hell you genius types drink these days)</em>. I want these posts to be a definitive guide, and the only way to do that is be thorough.</p></blockquote>
<p>Ok, here is the task we are completing in this post &#8211; Writing a simple (non-interactive) Python script to pull data from an Oracle table and insert it into a SQL Server table (and/or another Oracle database table). You can run it by hand on the command line or schedule it and it will always work the same &#8211; all the while using very little overhead.</p>
<p>I spend a lot of time in an old school Oracle shop and you&#8217;d be shocked how many people simply cannot do things this without resorting to ridiculous (and idiotic) methods (writing PL/SQL out to a flat file on the server, reading flat file in as an external table, etc.) &#8211; well, enough of that madness. Think of Python as the &#8220;glue&#8221; to stick things together <em>(WITHOUT ODBC or other shitty platform-dependent &#8220;connection technologies&#8221;)</em>.</p>
<p>If you&#8217;ve ever done any programming in the past, you&#8217;ll find that Python is a really easy and flexible language, which makes it very useful for doing just about any back-end task you&#8217;d want to accomplish &#8211; which (thankfully) includes grabbing extracts from virtually any database you can find a module for (and trust me, there is a lot) and then inserting that resultset into another database type.</p>
<p>I know I&#8217;ve defined the &#8220;task&#8221; above, but what my example script does specifically (in Part 1) is: Select some rows from an Oracle table (10g) put them into a list, and then use that list to insert them all into destination tables on Microsoft SQL Server (2005 / 2008) and another Oracle instance <em>(after truncating the destination tables, of course)</em>. <strong>&#8220;Trunc-n-load!&#8221;</strong></p>
<p>First we need set up the environment &#8211; for this example I&#8217;m going to be using a windows box <em>(since we need to connect to a SQL Server instance)</em>, you could do it all with a linux machine too, but for this particular example it&#8217;ll be on windows <em>(Linux tutorials coming up in the future)</em>.</p>
<p>I&#8217;m using <strong>Python 2.6.2</strong> which is the latest stable release in the 2.6 tree as of this writing. You can install it from the <a href="http://python.org/download/">Python.org site</a> using the MSI package if you want a nice and easy install.</p>
<h3>Now we need 2 Python modules for all this shiz-nit to work properly.</h3>
<p style="padding-left: 30px;"><a title="http://cx-oracle.sourceforge.net/" href="http://cx-oracle.sourceforge.net/"><strong>cx_Oracle</strong></a> <em>(for, you guessed it, connecting to Oracle)</em> &#8211; They&#8217;ve even got a <a href="http://prdownloads.sourceforge.net/cx-oracle/cx_Oracle-5.0.2-10g.win32-py2.6.msi?download">fancy MSI</a> for that too. I&#8217;m impressed.</p>
<p style="padding-left: 30px;"><strong><a href="http://sourceforge.net/projects/pymssql/files/">Pymssql</a></strong> <em>(for connecting to Microsoft SQL Server instances)</em> &#8211; Download the <a href="http://sourceforge.net/projects/pymssql/files/pymssql/1.0.2/pymssql-1.0.2.win32-py2.6.exe/download">install file</a> and run it. Its a lot easier than compiling the module from scratch <em>(esp since doing that requires Microsoft Visual Studio 2008)</em>.</p>
<p>Once those 2 are installed successfully &#8211; lets make sure they work.</p>
<p>Open up a command line Python interpreter&#8230; (you know <em>python.exe</em>)</p>
<h3><strong>&gt;&gt;&gt; import pymssql, cx_Oracle</strong></h3>
<p>You shouldn&#8217;t get any errors or response of any kind, just a new &#8216;&gt;&gt;&gt;&#8217; line below it. If so <strong>VIOLA! Its installed.</strong></p>
<h3>Now on to building the actual script.</h3>
<p>I&#8217;m going to go through the code chunk by chunk and comment on each section as we go, just in case you&#8217;re new to Python, but don&#8217;t worry I&#8217;ll have the entire file at the end for download <em>(with comments included in the code)</em>.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span>, pymssql, cx_Oracle<br />
<br />
<span style="color: #808080; font-style: italic;">## Define Oracle connection - format (&quot;username/password@TNSNAME&quot;)</span><br />
ora_conn = cx_Oracle.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;xxxx/xxxx@XXXXX&quot;</span><span style="color: black;">&#41;</span><br />
ora_cursor = ora_conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>&nbsp; <span style="color: #808080; font-style: italic;">#Allocate a cursor</span><br />
<br />
<span style="color: #808080; font-style: italic;">## Define the MSSQL server connection - format is self-explanatory</span><br />
mssql_conn = pymssql.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>host=<span style="color: #483d8b;">'xxxx'</span>, <span style="color: #dc143c;">user</span>=<span style="color: #483d8b;">'xx'</span>,<br />
password=<span style="color: #483d8b;">'xxx'</span>, database=<span style="color: #483d8b;">'XXX'</span><span style="color: black;">&#41;</span><br />
mssql_cursor = mssql_conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>&nbsp; <span style="color: #808080; font-style: italic;">#Allocate a cursor</span></div></div>
<p>Ok, first we&#8217;ve got our modules from above, <span style="text-decoration: line-through;">and we&#8217;re using &#8217;string&#8217; just for some output stuff that we&#8217;re doing later (just to check if its working)</span> <em>(update: I didn&#8217;t realize that I didn&#8217;t use the string module when I edited the script, I&#8217;ll still leave it in though &#8211; since we&#8217;ll need it in later more complicated posts)</em>. Then we&#8217;re defining the connection string and then defining a cursor that uses each connection &#8211; so we&#8217;re ready for hot SQL action.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">## Truncate our destination tables</span><br />
ora_cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;truncate table test&quot;</span><span style="color: black;">&#41;</span><br />
mssql_cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;truncate table test&quot;</span><span style="color: black;">&#41;</span></div></div>
<p>Truncate our destination tables (no mystery there). Notes: In this example I&#8217;m writing data to BOTH an Oracle table and a MS SQL table just to show you the different type of &#8220;insert many&#8221; that we have to use.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">## Grab our &quot;Source Data&quot;</span><br />
ora_cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&quot;&quot;SELECT DBMS_RANDOM.STRING('P',40) field1,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DBMS_RANDOM.STRING('X',30) field2,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ROUND(DBMS_RANDOM.VALUE(1000, 9999)) field3,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DBMS_RANDOM.STRING('A',20) field4<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM DUAL CONNECT BY LEVEL&amp;lt;=3000&quot;&quot;&quot;</span><span style="color: black;">&#41;</span></div></div>
<p>Ok, here is a simple select query into Oracle &#8211; I&#8217;m fetching some source rows to play with. This is just using some Oracle functions that generate random (crap) data &#8211; just for the sake of example.</p>
<p>I find it helpful in testing sometimes because using <strong>DBMS_RANDOM.STRING(&#8217;P',40)</strong> generates all kinds of characters that tend to break crappy apps and webapps due to un-escaped characters.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">## Transfer our cursor rows into a python list object</span><br />
ResultSet_Py_List = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> &nbsp;<span style="color: #808080; font-style: italic;">#Create an empty list</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> field1, field2, field3, field4 <span style="color: #ff7700;font-weight:bold;">in</span> ora_cursor:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">try</span>: &nbsp; <span style="color: #808080; font-style: italic;">#Then populate it with the cursor results</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ResultSet_Py_List.<span style="color: black;">append</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>field1, field2, field3, field4<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">except</span> <span style="color: #008000;">AttributeError</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">pass</span></div></div>
<p>Basically, here I create an empty list, called &#8216;ResultSet_Py_List&#8217;, and then iterate through all the fields and rows in the cursor <em>(which we filled up with data earlier)</em> and add them to it.</p>
<p><strong>Why?</strong> Well, first of all its easier to handle than the raw cursor object which can get tricky <em>(esp if we&#8217;re going to access the data twice)</em>, and secondly because if we&#8217;re going to do any data transformation later, it&#8217;ll be a fun party trick stunt as opposed to tragic.</p>
<p>When the cursor is empty, we have to do an <strong>except: pass</strong> so that the interpreter doesn&#8217;t freak out.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">## Quick count to see how many rows we're packin'!</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span><span style="color: #008000;">len</span><span style="color: black;">&#40;</span>ResultSet_Py_List<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' Records from Source'</span></div></div>
<p>This is pretty simple. I&#8217;m doing a count of all the rows in our list, just to make sure that its all loaded and ready to go. When I write command line apps <em>(even simple ones)</em>, I like to throw in logging and verbose stuff like this so I can better troubleshoot later. In this case we should see 3,000 rows in that baby.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">## Insert the list contents into Oracle, row by row...</span><br />
ora_cursor.<span style="color: black;">prepare</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&quot;&quot;INSERT INTO test(field1,field2,field3,field4)<br />
VALUES (:field1, :field2, :field3, :field4)&quot;&quot;&quot;</span><span style="color: black;">&#41;</span><br />
ora_cursor.<span style="color: black;">executemany</span><span style="color: black;">&#40;</span><span style="color: #008000;">None</span>, ResultSet_Py_List<span style="color: black;">&#41;</span><br />
ora_conn.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#COMMIT that shit before it gets away!</span></div></div>
<p>Ok, time for the INSERT into our Oracle DB table. You&#8217;ll see that we need to run a prepare with our parametrized query &#8211; then we can run an <strong>executemany</strong> with the list to kick it off. Then, bingo &#8211; commit it.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#Insert the list contents into Microsoft SQL table</span><br />
mssql_cursor.<span style="color: black;">executemany</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;&quot;&quot;INSERT INTO<br />
test (field1, field2, field3, field4)<br />
VALUES (%s, %s, %s, %s)&quot;&quot;&quot;</span>, ResultSet_Py_List<span style="color: black;">&#41;</span><br />
mssql_conn.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>Now its time for the MSSQL insertion, as you can see its a little different. Then we commit, and as they say &#8211; &#8220;Bob&#8217;s your Uncle&#8221;.</p>
<div class="codecolorer-container python vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:575px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ora_cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;select count(*) from test&quot;</span><span style="color: black;">&#41;</span><br />
ora_row_count = ora_cursor.<span style="color: black;">fetchone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>ora_row_count<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' Records INSERTED into Oracle table'</span><br />
<br />
mssql_cursor.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;select count(*) from test&quot;</span><span style="color: black;">&#41;</span><br />
mssql_row_count = mssql_cursor.<span style="color: black;">fetchone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>mssql_row_count<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span> + <span style="color: #483d8b;">' Records INSERTED into MSSQL table'</span><br />
<br />
<span style="color: #808080; font-style: italic;">## All done, Lars. Now lets get a drink.</span><br />
<br />
<span style="color: #808080; font-style: italic;">## We will even be nice and close the connections.</span><br />
<span style="color: #808080; font-style: italic;">## &nbsp; &nbsp; &nbsp; Its like tipping your hat to the Database engine.</span><br />
mssql_conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
ora_conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></div>
<p>All I&#8217;m doing here is counting the rows in each destination table and printing them on the screen, just so I&#8217;m SURE that everything went where it was supposed to be.</p>
<p>Now this was exceeding simplistic on purpose. I was people to be able to cut-n-paste properly and modify for their own liking. In the next post in the series, its going to get a bit more complicated, but this script is the &#8220;base&#8221; we&#8217;re going to build on for our <strong>Python-based ETL empire</strong>. So when people ask you what &#8220;ETL Tool&#8221; you use, you can say..<strong><em>&#8220;Umm, a text editor, bitch!&#8221;</em></strong></p>
<p>Here is the <a title="http://ryrobes.com/python_DTS.py" href="http://ryrobes.com/python_DTS.py">entire commented script file</a> for downloading (who wants to cut and paste over and over again from that shit above, I wouldn&#8217;t)!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=Bky8YbcF0o0:EDBxM1FMm8c:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=Bky8YbcF0o0:EDBxM1FMm8c:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=Bky8YbcF0o0:EDBxM1FMm8c:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=Bky8YbcF0o0:EDBxM1FMm8c:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=Bky8YbcF0o0:EDBxM1FMm8c:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=Bky8YbcF0o0:EDBxM1FMm8c:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/Bky8YbcF0o0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/featured-articles/using-a-simple-python-script-for-end-to-end-data-transformation-and-etl-part-1/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://ryrobes.com/featured-articles/using-a-simple-python-script-for-end-to-end-data-transformation-and-etl-part-1/</feedburner:origLink></item>
		<item>
		<title>I don’t mind ugly people, but I do mind people who make ugly faces…</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/d7CZxows0aU/</link>
		<comments>http://ryrobes.com/lifestyle/i-dont-mind-ugly-people-but-i-do-mind-people-who-make-ugly-faces/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 01:59:50 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Lifestyle]]></category>
		<category><![CDATA[Perception]]></category>
		<category><![CDATA[attitude]]></category>
		<category><![CDATA[snobs]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=83</guid>
		<description><![CDATA[I saw a girl today crossing the street in front of me as I patiently sat at a red light. My first reaction was pretty neutral &#8211; I thought, &#8220;Eh, its just some cute, young college girl&#8221; &#8211; my city is full of them due to all the schools in the capital district, and they [...]]]></description>
			<content:encoded><![CDATA[<p>I saw a girl today crossing the street in front of me as I patiently sat at a red light. My first reaction was pretty neutral &#8211; I thought, &#8220;Eh, its just some cute, young college girl&#8221; &#8211; my city is full of them due to all the schools in the capital district, and they all seem to want to live in my area too.</p>
<h3>They&#8217;re like cockroaches with designer purses and huge sunglasses.</h3>
<p><em>(think <strong>Gossip Girl</strong> meets <strong>Cruel Intentions</strong> meets <strong>House Bunny</strong>)</em></p>
<p>But then a funny thing happened &#8211; she must have seen something across the street, or thought of something disagreeable and suddenly her face twisted into a snarl that I can only describe as utter disgust (and before you say it, No, its NOT because she saw ME either &#8211; she was totally oblivious to any type of automobile, mobile or stationary, like a typical Albany pedestrian). It was like in &#8216;The Ring&#8217; when they find that dead High School girl in the closet &#8211; just a twisted Stan Winston monster make-up face.</p>
<h2>Bam.</h2>
<p>This one look totally changed my opinion of her. She went from &#8220;Cute&#8221; to a &#8220;Spoiled Asshole&#8221; in the blink of an eye. Granted, I don&#8217;t know this person &#8211; and never will, but it just goes to show you how powerful your body language is at all times.</p>
<h2>Why did this happen? I&#8217;ll tell you.</h2>
<p>You face is just a reflection of whats behind it. If you look dumb all the time, well&#8230; chances are, you aren&#8217;t the sharpest crayon in the box.</p>
<p>When you scowl constantly for seemingly no reason &#8211; <strong>it tells me 3 things:</strong></p>
<ol>
<li>you&#8217;re constantly thinking of things that displease you <em>(or EVERYTHING displeases you)</em></li>
<li>you really don&#8217;t appreciate anything</li>
<li>are generally a super negative asshole</li>
</ol>
<p>Think I&#8217;m over-reacting? Maybe a tad, but the very fact that I don&#8217;t even KNOW this person makes my case much stronger. Why?</p>
<p>Its all about PERCEPTION, baby.</p>
<p>It doesn&#8217;t matter if she&#8217;s the nicest girl in the world who happened to step on skunk and made the face out of pure olfactory reactions. I saw what I saw and labeled her an ahole. Simple as that.</p>
<p>People who don&#8217;t know us make snap judgements all day long &#8211; and I&#8217;d be willing to bet that they&#8217;ve got a 50% error rate, which is pretty good. That alone should tell you something about the importance of human communications through body language.</p>
<p>So do me a favor, next time your walking down the street and you&#8217;re aware that people are looking at you.</p>
<h2>Smile for a change.</h2>
<p>You never know what kind of opportunity might knock when you aren&#8217;t scaring people away with your jerky facial attacks.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=d7CZxows0aU:riWrT7aH7TI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=d7CZxows0aU:riWrT7aH7TI:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=d7CZxows0aU:riWrT7aH7TI:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=d7CZxows0aU:riWrT7aH7TI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=d7CZxows0aU:riWrT7aH7TI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=d7CZxows0aU:riWrT7aH7TI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/d7CZxows0aU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/lifestyle/i-dont-mind-ugly-people-but-i-do-mind-people-who-make-ugly-faces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/lifestyle/i-dont-mind-ugly-people-but-i-do-mind-people-who-make-ugly-faces/</feedburner:origLink></item>
		<item>
		<title>The State of Flow, Hidden Passions, and Drudgery</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/hR2_6B0ORZw/</link>
		<comments>http://ryrobes.com/featured-articles/the-state-of-flow-hidden-passions-and-drudgery/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 03:01:50 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Flow]]></category>
		<category><![CDATA[Lifestyle]]></category>
		<category><![CDATA[Passion]]></category>
		<category><![CDATA[Career]]></category>
		<category><![CDATA[Lifestlye]]></category>
		<category><![CDATA[State of Flow]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=28</guid>
		<description><![CDATA[Have you ever had an activity that you became totally lost in &#8211; where time either flashed by in an instant or seemed to stand still &#8211; your entire concentration was on that task at hand and the rest of the world just kind of faded away temporarily?
Well, then you have experienced the &#8220;State of [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever had an activity that you became totally lost in &#8211; where time either flashed by in an instant or seemed to stand still &#8211; your entire concentration was on that task at hand and the rest of the world just kind of faded away temporarily?</p>
<p>Well, then you have experienced the &#8220;<strong>State of Flow</strong>&#8220;. Some people call it different weird things, such as &#8220;In The Zone&#8221; or &#8220;In The Moment&#8221; &#8211; but I think that &#8220;Flow&#8221; sums it up the best.</p>
<p>It could be anything, it could be painting, photography, gardening, whatever it is that really makes your brain come alive and completely DEVOUR the task at hand. This is the kind of activity that makes you think, challenges you, and makes you thrive at the same time. Its the challenge portion that I always enjoy &#8211; you can&#8217;t enter that state by doing easy tasks. It has to be just challenging enough to both be do-able AND be difficult at the same time, as paradoxical (is that a word?) as it may sound.</p>
<p>The key to long term happiness is finding something that consistently does this for you. If you can actually make a living doing that &#8220;Flow task&#8221; then that&#8217;s pretty much the Holy Grail right there.</p>
<p>Currently, I make my living as a programmer <em>(by &#8220;living&#8221; I mean it pays the bills &#8211; it doesn&#8217;t make me &#8220;live&#8221; or come &#8220;alive&#8221; by any stretch of the imagination)</em>.</p>
<p>To be completely honest, I used to love it <em>(or I at least THOUGHT that I did at the time)</em>, and even today when presented with a small project that has a lot of problem solving and intricate detail in it &#8211; I almost always enter a state of Flow for a period of time. It has to be something complicated but not huge and unwieldy &#8211; and also something that can be knocked off in a day or two that requires no other person to work on it except for me (waiting for other idiots to do their jobs properly is a huge &#8220;Flow Breaker&#8221; for me).</p>
<h4>So that&#8217;s awesome, right? I&#8217;ve won &#8211; since I get flow at my day job?</h4>
<h2>Nope, Not at all.</h2>
<p>After being in this business for 13 years now, I&#8217;ve come to realize that most of what was so novel and intriguing to me in the late 90s (when I came on board in this industry as a young pup) is now just mundane regurgitated bullshit. Not only that, but my little islands of &#8220;Flow&#8221; that I DO manage to get these days probably only really happen 10% of the time &#8211; the other 90% is pretty excruciating (project meetings, arguing about specs, team infighting, political state-related policy changes, the utter stagnation of the IT department heads, etc).</p>
<p>It makes me think that the last industry I left (being an auto mechanic for a well-known local Volkswagen dealership) actually had more &#8216;happiness merit&#8217; than my much higher paying IT jobs that followed it (Systems Integrator, System / Network Admin, Senior Programmer, Consultant). I was able to achieve Flow there too, but it had to be on something interesting and unknown that required a good amount of digging and testing &#8211; and yes, that job had a good deal of the mundane and menial tasks as well.</p>
<p>What are similarities? They are both rooted in problem solving for <em>(mostly cause and effect based)</em> complicated systems.</p>
<p>So if you can find a generalized idea like that &#8211; how do we extract it and apply it to something that we WANT to do AND can get paid for?</p>
<p><strong>Its a good question, and one I&#8217;m currently chewing on over the past month or so.</strong></p>
<p>I think we have to go back to the beginning and try to re-discover our passions in life. It sounds pretty corny, but its true. If your job is just &#8220;paying the bills&#8221; and you aren&#8217;t happy, maybe its worth a shot. Think back to when you were little &#8211; kids have this awesome ability to just list things that they &#8220;love&#8221; to do. Adults tend to over-think it and come up with answers that are much less honest&#8230;</p>
<p>Try it &#8211; ask the little kid inside you, <em><strong>&#8220;What do you love to do?&#8221;</strong></em> &#8211; Write them down and give them a try, you might be surprised.</p>
<h2>What can you re-discover?</h2>
<h4>It might just change your outlook on your CURRENT life.</h4>
<p><em>(image from <a title="http://www.flickr.com/photos/fairuz_frz/" href="http://www.flickr.com/photos/fairuz_frz/">mr_fairuz&#8217;s Flickr</a>)</em></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hR2_6B0ORZw:gYgKWk9YC94:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hR2_6B0ORZw:gYgKWk9YC94:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hR2_6B0ORZw:gYgKWk9YC94:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hR2_6B0ORZw:gYgKWk9YC94:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=hR2_6B0ORZw:gYgKWk9YC94:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=hR2_6B0ORZw:gYgKWk9YC94:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/hR2_6B0ORZw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/featured-articles/the-state-of-flow-hidden-passions-and-drudgery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/featured-articles/the-state-of-flow-hidden-passions-and-drudgery/</feedburner:origLink></item>
		<item>
		<title>Bike Path + Reflective Sunglasses = Mean Walkers</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/pJ-3OJLMWok/</link>
		<comments>http://ryrobes.com/random/bike-path-reflective-sunglasses-mean-walkers/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 04:23:26 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[bike path]]></category>
		<category><![CDATA[flipcam]]></category>
		<category><![CDATA[sociology]]></category>
		<category><![CDATA[summer]]></category>
		<category><![CDATA[sunglasses]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=17</guid>
		<description><![CDATA[This is just a test of the FlipCam + uploading to YouTube + Posting in Wordpress. Don&#8217;t expect anything amazing. 




]]></description>
			<content:encoded><![CDATA[<p>This is just a test of the FlipCam + uploading to YouTube + Posting in Wordpress. Don&#8217;t expect anything amazing. </p>
<p><br/></p>
<div align="center">
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" height="337" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/YOtz7Wrnz-A&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="560" height="337" src="http://www.youtube.com/v/YOtz7Wrnz-A&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x3a3a3a&amp;color2=0x999999" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=pJ-3OJLMWok:WPXvvzhy-Hc:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=pJ-3OJLMWok:WPXvvzhy-Hc:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=pJ-3OJLMWok:WPXvvzhy-Hc:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=pJ-3OJLMWok:WPXvvzhy-Hc:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=pJ-3OJLMWok:WPXvvzhy-Hc:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=pJ-3OJLMWok:WPXvvzhy-Hc:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/pJ-3OJLMWok" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/random/bike-path-reflective-sunglasses-mean-walkers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://ryrobes.com/random/bike-path-reflective-sunglasses-mean-walkers/</feedburner:origLink></item>
		<item>
		<title>The UFC needs a Michael Jordan, not a Michael Vick</title>
		<link>http://feedproxy.google.com/~r/Ryrobes/~3/k9ZhNW7-c2w/</link>
		<comments>http://ryrobes.com/marketing/what-the-ufc-needs-is-a-michael-jordan-not-a-michael-vick/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 00:59:06 +0000</pubDate>
		<dc:creator>Ry</dc:creator>
				<category><![CDATA[Featured Articles]]></category>
		<category><![CDATA[Marketing]]></category>
		<category><![CDATA[Public Relations]]></category>
		<category><![CDATA[Ramble]]></category>
		<category><![CDATA[Random]]></category>
		<category><![CDATA[Brock Lesnar]]></category>
		<category><![CDATA[Brock Lesner]]></category>
		<category><![CDATA[UFC]]></category>
		<category><![CDATA[UFC 100]]></category>

		<guid isPermaLink="false">http://ryrobes.com/?p=3</guid>
		<description><![CDATA[You stay classy, Brock Lesnar!
Before you think I&#8217;m just writing a rant (which it is), take a minute to think about how this relates in the marketing world. Its somewhere between an industrial accident and a PR stunt, depending on where the truth lies and who you believe. Either way, its creating a new branding [...]]]></description>
			<content:encoded><![CDATA[<h2>You stay classy, Brock Lesnar!</h2>
<p>Before you think I&#8217;m just writing a rant <em>(which it is)</em>, take a minute to think about how this relates in the marketing world. Its somewhere between an industrial accident and a PR stunt, depending on where the truth lies and who you believe. Either way, its creating a new branding message in the WRONG direction (in my opinion).</p>
<p>Now I know this subject has been beaten to death since the fight on Saturday night (which I paid $45 to watch at home in lieu of &#8216;hitting the town&#8217; for it and probably ended up SAVING myself money, but I digress). I&#8217;m actually glad that I waited and let the whole situation &#8220;marinade&#8221; in my mind for a few days first.</p>
<p>Straight-up, I don&#8217;t like Brock Lesnar. I&#8217;ve been that way since he came up and tried to make a fool out of Couture a few months ago. He&#8217;s just seems like a big loud bully (ok, maybe &#8216;big&#8217; is an understatement), which all works fine in the WWE where he&#8217;s basically a trumped-up character actor with some beefcake acrobatics thrown in. The UFC is real life and we expect a little more depth in our competitors &#8211; Honestly, I don&#8217;t think thats asking for too much, is it?</p>
<p>Yet, he continues to be the stereotypical &#8216;bad guy&#8217; that we&#8217;d expect from the theatrical &#8216;performances&#8217; that WWE (and WWF in the old days) deliver. He pretty much proved this on Saturday night with his bizarre victory speech with Joe Rogan (I mean, really, are supposed to give a fuck that Bud Light didn&#8217;t show him any sponsorship love and Coors did? No. Why is he even fishing for sponsors at this stage in his UFC career? I like to actually semi-respect the people that schlep the crap that I buy. Just do your job, asshole. Oh yeah, nice job at calling out a big UFC corporate sponsor at the same time too.)</p>
<p>I also like the little weak attempt to retract the outburst on Sunday, which is just a day-after attention-whoring move to get the last drop out of it. &#8220;What did he say? OMG!&#8221; Blah, Blah, Blah.</p>
<p>They (He) can play their game, it may get some media coverage initially and people might be talking about it &#8211; but I personally think that its an extremely bad move, especially now in what is a VERY important time for UFC and MMA as a professional sport on the whole. They are on the cusp of, dare I say it, mainstream legitimacy &#8211; and who is our champion? Who rides on white stallions bravely carrying the shield of his beloved sport?</p>
<h4>Some badly tattooed asshole who looks like he&#8217;s one of Hitler&#8217;s undead Aryan minions from &#8216;Return to Castle Wolfenstein&#8217;? Good god, I hope to hell not.</h4>
<p>Now I&#8217;m all for the UFC and Dana White making money. He can have diamond toilet seats for all I care &#8211; but if he&#8217;s at all concerned with the &#8216;big picture&#8217; and his legacy with the sport, he needs to rein this clown in now and do some serious marketing to try and prove to us that he&#8217;s an actual interesting human being.</p>
<p style="padding-left: 30px;">In a sport that naturally generates actual human drama, we don&#8217;t need artificial voltage like boobie tassels, &#8220;Yo Momma so fat&#8221; moments, or fake ego battles.</p>
<p>People are speculating that Dana White did all this on purpose in order to try and capitalize on the type of viewership (and affiliated merchandising) that the WWE crowd generates. If thats true, if just hope that he realizes that he&#8217;s taking his (and the UFCs) credibility down several critical notches at the same time.</p>
<p>Maybe I&#8217;m wrong, and its all really a big &#8220;mis-understanding&#8221; and &#8220;mis-communication&#8221;.</p>
<p>I guess we&#8217;ll all know the answer to that is on the next Pay-Per-View event Brock rides up to the Octagon on a Harley-Davidson with a big snake around his shoulders and his silicone encumbered &#8216;wife&#8217; on the back (oh, and don&#8217;t forget the Coors Light girls behind them).</p>
<h4 style="padding-left: 30px;">Yikes. Then maybe its time start watching something else instead.</h4>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/Ryrobes?a=k9ZhNW7-c2w:I6JnWAO1hdA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=k9ZhNW7-c2w:I6JnWAO1hdA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=k9ZhNW7-c2w:I6JnWAO1hdA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=k9ZhNW7-c2w:I6JnWAO1hdA:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/Ryrobes?i=k9ZhNW7-c2w:I6JnWAO1hdA:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/Ryrobes?a=k9ZhNW7-c2w:I6JnWAO1hdA:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/Ryrobes?d=qj6IDK7rITs" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Ryrobes/~4/k9ZhNW7-c2w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://ryrobes.com/marketing/what-the-ufc-needs-is-a-michael-jordan-not-a-michael-vick/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://ryrobes.com/marketing/what-the-ufc-needs-is-a-michael-jordan-not-a-michael-vick/</feedburner:origLink></item>
	</channel>
</rss>
