<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Jon Saints</title>
    <description>source code for saintsjd.com</description>
    <link>https://www.saintsjd.com/</link>
    <atom:link href="https://www.saintsjd.com/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Wed, 20 Nov 2024 03:25:08 +0000</pubDate>
    <lastBuildDate>Wed, 20 Nov 2024 03:25:08 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>A Better Way to Visualize Your Organization - Trees instead of Squids</title>
        <description>&lt;p&gt;Companies often represent their organization structure in a hierarchical org chart. These charts start at the top with the President/CEO. From there, they sprawl down and out through the ranks to those doers and newbies at the “bottom” of the org. Charts like this look like a squid.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/org-chart.png&quot; alt=&quot;hierarchical org chart with ceo at the top and reports shown below&quot; class=&quot;inline&quot; height=&quot;400&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I am not a fan of drawing things this way.&lt;/p&gt;

&lt;p&gt;An alternative to the hierarchical org chart is the org tree. The org tree flips the org chart upside down. It starts with the President/CEO at the bottom, like the trunk of a tree. From there branches are formed which support smaller and smaller branches. Finally, the leaves represent those at the “top” -  the experienced doers and up-and-coming newbies of the organization.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/img/org-tree.png&quot; alt=&quot;org tree with ceo at the bottom and reports shown above&quot; class=&quot;inline&quot; height=&quot;400&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The tree view tells a powerful organizational story which I like much more:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Those at the bottom of this org carry weight. They support. They empower. They are experienced anchors in times of change. Their goal is to ensure the thriving of the people in their branch.&lt;/li&gt;
  &lt;li&gt;The doers and newbies at the top of the org are valued. They are vital. They are the most supported and empowered to do the work that is critical to the org’s success.&lt;/li&gt;
  &lt;li&gt;We all matter. We all depend on each other. We co-exist to serve our customer.&lt;/li&gt;
  &lt;li&gt;Power and influence come from doing your part really well and supporting more and more people with your work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which organization would you want to be a part of? Which leader’s vision would you want to follow?&lt;/p&gt;

</description>
        <pubDate>Sun, 18 Apr 2021 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2021/04/18/org-trees.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2021/04/18/org-trees.html</guid>
        
        <category>word</category>
        
        
      </item>
    
      <item>
        <title>Lucas Clay Saints</title>
        <description>&lt;p&gt;On Saturday, May 9, 2015 at 9:19pm we welcomed our second baby boy into the family. Lucas Clay Saints was born in the water at the Birth Center of Boulder to a happy healthy Mom and an excited Dad.  He was born after nearly two weeks of cloudy spring rains, capped off by a May snow storm on the Eve of Mother’s Day.&lt;/p&gt;

&lt;p&gt;As the second-born, baby Luca joins our family mid-stream, representing new growth and bringing us new love, new perspective and new joy.  The name Lucas means bearer of light, light giving or illumination. Our home and our hearts are already filled with new light.&lt;/p&gt;

&lt;p&gt;His middle name, Clay, is a shout-out to art and to creation. It’s inspired by his mother and the deep colorful way that she lives. It is a reference to vibrant colors of clay we have seen in our travels around the world. It is a reminder of our roots in the dust and clay, our connection to the earth and our God that created it all. That life was blown into all of us as a gift. You are dust and to dust you shall return, but your spirit endures forever. By giving the name Clay, we hope it grounds him in the knowledge that he is shaped by Potters hands, and that he can be a channel for this source of creativity bringing beauty into this world.&lt;/p&gt;

&lt;p&gt;We cherish the bond that Rio and Luca will build as brothers.  Rio is already such a sweet, proud, big brother to baby Luca.&lt;/p&gt;

&lt;p&gt;The birth experience with Luca was quite different from Rio.  The labor was swift and intense lasting only 5 hours.  We rushed to the Birth Center in Boulder as soon as Marissa noticed her first contractions. They were already close together and getting stronger by the minute.  While Rio’s birth was private and personal, Luca’s birth can best be described as a party. The birth was attended by his three Grandmas, our good family friend Cinda, big brother Rio, our wonderful friend and doula Lara, the midwife and nurse. Plus, as a bonus, Grandpa and Uncle Andrew were eagerly waiting and entertaining Rio just outside the birthing room.&lt;/p&gt;

&lt;p&gt;We are astounded already by the immense capacity of the heart to love and expand as our family grows. Welcome to the Saints family, precious Luca.&lt;/p&gt;

&lt;p&gt;Love
Jon and Marissa&lt;/p&gt;
</description>
        <pubDate>Tue, 12 May 2015 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2015/05/12/lucas-clay-saints.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2015/05/12/lucas-clay-saints.html</guid>
        
        <category>family</category>
        
        
      </item>
    
      <item>
        <title>Export Postgres Query to CSV</title>
        <description>&lt;p&gt;Postgres makes it easy to export a query a remote server and save the results to CSV on your local machine.&lt;/p&gt;

&lt;p&gt;First, connect to the remote database server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;psql -h REMOTE_SERVER_ADDRESS -U DB_USER -W
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, export a query to CSV… &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\copy&lt;/code&gt; makes the file go to your local machine rather than the database server file system&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;\copy (select * from my_table limit 10) TO &apos;~/Downloads/export.csv&apos; CSV HEADER
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Thu, 20 Nov 2014 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2014/11/20/export-postgres-query-to-csv.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2014/11/20/export-postgres-query-to-csv.html</guid>
        
        <category>development</category>
        
        <category>opensource</category>
        
        <category>postgresql</category>
        
        <category>postgres</category>
        
        
      </item>
    
      <item>
        <title>Simple Postgresql Database Connections with Python</title>
        <description>&lt;h3 id=&quot;update&quot;&gt;UPDATE:&lt;/h3&gt;

&lt;p&gt;I’ve spent some time using the method that I outlined below and found some problems with it. I now have a new prefered way of querying postgres from python and getting results as a dictionary. You should use the new way in most cases.&lt;/p&gt;

&lt;p&gt;Here are the problems with the previous method:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The previous method requires sqlalchemy which is a large dependency&lt;/li&gt;
  &lt;li&gt;The previous method was using a sqlalchemy connection pool and leaving connections open too long. This was a problem when I tried to us this code in background worker tasks that needed to control when connections are closed (so they could open a connection, read some data, disconnect, run a calculation for a while, then re-connect and write back to the database). Leaving the connections open in a pool in sqlalchemy on a large set of workers was consuming all the available connections to the databse.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My new suggestion is to use psycopg2 and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;with&lt;/code&gt; statement to ensure that connections are efficient and handled properly by garbage collection when they are no longer in use.&lt;/p&gt;

&lt;p&gt;http://initd.org/psycopg/docs/usage.html#with-statement&lt;/p&gt;

&lt;p&gt;See also the psycopg2 list of Best Practices:&lt;/p&gt;

&lt;p&gt;http://initd.org/psycopg/docs/faq.html#best-practices&lt;/p&gt;

&lt;p&gt;There is also a dictcursor which will give you results as python dictionaries:&lt;/p&gt;

&lt;p&gt;http://initd.org/psycopg/docs/extras.html#dictionary-like-cursor&lt;/p&gt;

&lt;h3 id=&quot;outdated-the-ideas-below-are-out-of-date--see-above&quot;&gt;OUTDATED: The ideas below are out of date…  see above&lt;/h3&gt;

&lt;p&gt;Deep in the SQLAlchemy docs, I found this gem: a simple way of querying a database from Python that returns query results as a python dictionary.&lt;/p&gt;

&lt;p&gt;First, setup a virtualenv for your project and install SQLAlchemy and psycopg2&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd my_app
virtualenv venv
. venv/bin/activate
pip install SQlAlchemy
pip install psycopg2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, with just a few lines you can run queries from your python scripts. Results are returned as python dictionaries:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sqlalchemy&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_engine&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_engine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;postgresql://scott:tiger@localhost/mydatabase&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;select * from users where fname=%s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Jon&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;username:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;username&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;email:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;email&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;First Name:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;fname&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are a few advantages to doing things this way:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Easier syntax than the raw psycopg2 driver&lt;/li&gt;
  &lt;li&gt;Uses SQLAlchemy connection pooling by default&lt;/li&gt;
  &lt;li&gt;It appears that SQLAlchemy does the right thing and closes connections if an exception is thrown or the script exits successfully.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: To install psycopg2 on my Mac I had to first install &lt;a href=&quot;http://postgresapp.com/&quot;&gt;Postgres.app&lt;/a&gt; and set my PATH in .bash_profile to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PATH=&quot;/Applications/Postgres.app/Contents/Versions/9.3/bin:$PATH&quot;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note: If you are on Ubuntu you will need to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo apt-get install libpq-dev python-dev&lt;/code&gt; before running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install psycopg2&lt;/code&gt;&lt;/p&gt;
</description>
        <pubDate>Wed, 15 Oct 2014 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2014/10/15/simple-postgresql-database-connections-python.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2014/10/15/simple-postgresql-database-connections-python.html</guid>
        
        <category>development</category>
        
        <category>opensource</category>
        
        <category>python</category>
        
        
      </item>
    
      <item>
        <title>Howto install Postgresql and PostGIS on Ubuntu Trusty 14.04 with secure tunnel for connections</title>
        <description>&lt;h3 id=&quot;install-ubuntu-1404&quot;&gt;Install Ubuntu 14.04&lt;/h3&gt;

&lt;p&gt;Start with a fresh install of Ubuntu 14.04 Trusty. (AWS or vagrant might be a good way.)&lt;/p&gt;

&lt;h3 id=&quot;install-postgresql&quot;&gt;Install Postgresql&lt;/h3&gt;

&lt;p&gt;On the server run the commands below.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get update
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; postgresql postgresql-contrib&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;create-a-database-and-a-user-to-access-it&quot;&gt;Create a database and a user to access it&lt;/h3&gt;

&lt;p&gt;I prefer to create one user per database for security.&lt;/p&gt;

&lt;p&gt;Replace DATABASE_NAME_HERE and USER_NAME_HERE with the values that you want to use&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;c&quot;&gt;# this will prompt you for a database password&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; postgres createuser &lt;span class=&quot;nt&quot;&gt;-P&lt;/span&gt; USER_NAME_HERE
&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; postgres createdb &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; USER_NAME_HERE DATABASE_NAME_HERE&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;test-connecting-to-postgresql&quot;&gt;Test connecting to Postgresql&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;psql &lt;span class=&quot;nt&quot;&gt;-h&lt;/span&gt; localhost &lt;span class=&quot;nt&quot;&gt;-U&lt;/span&gt; USER_NAME_HERE DATABASE_NAME_HERE&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Postgresql will ask you for your password. Then you should see:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;psql &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;9.3.5&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
SSL connection &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;cipher: DHE-RSA-AES256-SHA, bits: 256&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Type &lt;span class=&quot;s2&quot;&gt;&quot;help&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;help.

&lt;span class=&quot;nv&quot;&gt;DATABASE_NAME_HERE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;To exit type:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;se&quot;&gt;\q&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;optional-add-postgis-support-to-the-database&quot;&gt;Optional: Add PostGIS support to the database&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; postgis postgresql-9.3-postgis-2.1
&lt;span class=&quot;nb&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt; postgres psql &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;CREATE EXTENSION postgis; CREATE EXTENSION postgis_topology;&quot;&lt;/span&gt; DATABASE_NAME_HERE&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;connect-to-the-database-securely-from-pgadmin3&quot;&gt;Connect to the database securely from PgAdmin3&lt;/h3&gt;

&lt;p&gt;Now, on your desktop computer install pgAdmin3 and connect securely to the database via an SSH tunnel.&lt;/p&gt;

&lt;p&gt;First, open a terminal on your Desktop computer (these instructions are for Mac or Linux)&lt;/p&gt;

&lt;p&gt;Open a tunnel using an ssh password or PEM file. You will need to know the username you use to SSH to the server and the server address or ip address.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;ssh &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; 127.0.0.1:5433:127.0.0.1:5432 SSH_USERNAME_HERE@SERVER_HOST_ADDRESS &lt;span class=&quot;nt&quot;&gt;-N&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you are using a PEM file, then you can add -i option to the SSH command&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; PEM_FILE_PATH_HERE.pem&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This will open a secure tunnel between your desktop and the database server. To exit the tunnel, just press Cntrl+C.&lt;/p&gt;

&lt;p&gt;Next, open pgAdmin3 and create a new connection using these settings:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Name: &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;describe what this connection is &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;here&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
Host: 127.0.0.1
Port: 5433
Username: USERNAME_HERE
Password: PASS_WORD_HERE&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When you are done using the database close PgAdmin3 and in the terminal where the tunnel is running press Cntrl+c to exit the tunnel.&lt;/p&gt;
</description>
        <pubDate>Wed, 13 Aug 2014 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2014/08/13/howto-install-postgis-on-ubuntu-trusty.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2014/08/13/howto-install-postgis-on-ubuntu-trusty.html</guid>
        
        <category>development</category>
        
        <category>geo</category>
        
        
      </item>
    
      <item>
        <title>Howto install libgeos with PHP5 bindings on Ubuntu Trusty 14.04 LTS</title>
        <description>&lt;p&gt;Recently I needed to install libgeos with PHP5 bindings on Ubuntu 14.04 LTS. The PHP5 bindings are not available as a package in Ubuntu. Here is how I installed it from source.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; apache2 php5 libapache2-mod-php5 php5-dev phpunit

wget http://download.osgeo.org/geos/geos-3.4.2.tar.bz2
&lt;span class=&quot;nb&quot;&gt;tar&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-xjvf&lt;/span&gt; geos-3.4.2.tar.bz2
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;geos-3.4.2/
./configure &lt;span class=&quot;nt&quot;&gt;--enable-php&lt;/span&gt;
make
make &lt;span class=&quot;nb&quot;&gt;install

cat&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /etc/php5/mods-available/geos.ini &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;EOF&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
; configuration for php geos module
; priority=50
extension=geos.so
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOF

&lt;/span&gt;php5enmod geos
service apache2 restart

&lt;span class=&quot;c&quot;&gt;# note: you might need to run ldconfig here if you see permissions issues. I don&apos;t see it on my setup, but users in the comments have&lt;/span&gt;
ldconfig&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can test this in a test.php file with&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-php&quot; data-lang=&quot;php&quot;&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GEOSVersion&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

</description>
        <pubDate>Thu, 05 Jun 2014 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2014/06/05/howto-intsall-libgeos-with-php5-bindings-ubuntu-trusty-14.04.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2014/06/05/howto-intsall-libgeos-with-php5-bindings-ubuntu-trusty-14.04.html</guid>
        
        <category>development</category>
        
        <category>geo</category>
        
        
      </item>
    
      <item>
        <title>Run Vendored Binaries on Heroku</title>
        <description>&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;Often on Heroku your app might depend on a system package that is not installed in the base Heroku system. Including an external binary dependency in your Heroku app is easy. These binaries are called vendored binaries.&lt;/p&gt;

&lt;p&gt;Here is a quick summary of how to do this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Compile the binary on the heroku platform using a one-off dyno bash prompt &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;heroku run /bin/bash&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Copy the compiled package to your local git repo and place it in a folder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.heroku/vendor&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On your next push to heroku, the system path will recognize the binary dependencies in your path LD_LIBRARY_PATH.&lt;/p&gt;

&lt;h3 id=&quot;background&quot;&gt;Background&lt;/h3&gt;

&lt;p&gt;Recently I needed to install the python &lt;a href=&quot;https://pypi.python.org/pypi/Shapely&quot;&gt;Shapely&lt;/a&gt; library on a Heroku app. Shapely has a dependency on the C Library &lt;a href=&quot;http://trac.osgeo.org/geos/&quot;&gt;GEOS&lt;/a&gt; which is not part of the base Heroku system.&lt;/p&gt;

&lt;p&gt;Here is how I complied and vendored the GEOS binary for Heroku. You could use the same process to vendor a different binary.&lt;/p&gt;

&lt;h3 id=&quot;step-1-setup-your-git-repository-and-heroku-app-locally&quot;&gt;Step #1: Setup your git repository and heroku app locally&lt;/h3&gt;

&lt;p&gt;I assume you have read and followed the appropriate Heroku Getting Started Guide for your language. I used &lt;a href=&quot;https://devcenter.heroku.com/articles/getting-started-with-python&quot;&gt;Getting Started with Python on Heroku&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;step-2-compile-binaries-on-heroku&quot;&gt;Step #2: Compile binaries on Heroku&lt;/h3&gt;

&lt;p&gt;With your application configured, run bash on a Heroku process&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;heroku run /bin/bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;From the Heroku bash command prompt, download and extract the source code for the binary package you need to run on Heroku. In my case it was:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -O http://download.osgeo.org/geos/geos-3.4.2.tar.bz2
tar -xjvf geos-3.4.2.tar.bz2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Open the README or the INSTALL doc for your source code and follow the compile instructions with one change. Change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;prefix&lt;/code&gt; for the install to be something easy to find in your /app folder.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd geos-3.4.2
./configure --prefix=/app/.heroku/vendor
make
make install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When the compiling is finished you will have a working binary in the /app/scratch-space folder. In my case geos made three folders in the scratch-space folder: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lib&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Create an zip archive of the binaries.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tar -czvf /app/geos-3.4.2-heroku.tar.gz .heroku/vendor
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;step-3-add-the-vendor-library-to-your-local-source-control&quot;&gt;Step #3: Add the vendor library to your local source control&lt;/h3&gt;

&lt;p&gt;Next copy the geos-3.4.2-heroku.tar.gz to your local machine. I did this in two steps. You might have a better method. I used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scp&lt;/code&gt; to copy the file to another server and then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;scp&lt;/code&gt; again copy the geos-3.4.2-heroku.tar.gz to my local machine.&lt;/p&gt;

&lt;p&gt;With the geos-3.4.2-heroku.tar.gz on your local machine extract it into a folder .heroku/vendor in the root of your app. Heroku will automatically add the .heroku/vendor folder to your LD_LIBRARY_PATH.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# from my app root folder
mkdir .heroku
mkdir .heroku/vendor
tar -xzvf ~/Downloads/geos-3.4.2-heroku.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Make sure you have the same folder structure as scratch-space in .heroku/vendor. In my case I have three folders: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lib&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;include&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ls .heroku/vendor
bin include lib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Add the binaries to your git repo and deploy to Heroku. The binaries will be available to your app.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git add .
git commit -m &quot;vendored binary for lib geos&quot;
git push heroku master
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;optional-step-4-use-buildpacks-instead-of-adding-binaries-to-local-git-repo&quot;&gt;Optional Step #4: Use buildpacks instead of adding binaries to local git repo&lt;/h3&gt;

&lt;p&gt;Instead of Step #3 you can also use the &lt;a href=&quot;https://github.com/ddollar/heroku-buildpack-multi&quot;&gt;Multi Buildpack&lt;/a&gt; and the &lt;a href=&quot;https://github.com/peterkeen/heroku-buildpack-vendorbinaries&quot;&gt;Vendored Libraries Buildpack&lt;/a&gt; build if you prefer not to have vendored binaries in your git repo.&lt;/p&gt;

&lt;p&gt;You will want to modify your tar.gz file from Step #2 so that it extracts its contents to .heroku/vendor/BINARY_FILES_HERE.&lt;/p&gt;

&lt;p&gt;Then copy your binary from Step #2 to amazon s3. Make the URL public.&lt;/p&gt;

&lt;p&gt;Install Multi build pack support. See https://github.com/ddollar/heroku-buildpack-multi&lt;/p&gt;

&lt;p&gt;Install Vendored Binary buildpack support and create a .vendor_urls file  and add your S3 url to the tar.gz to it.&lt;/p&gt;

&lt;h3 id=&quot;note-on-installing-libgeos-php-bindings-on-heroku&quot;&gt;Note on Installing libgeos PHP bindings on Heroku&lt;/h3&gt;

&lt;p&gt;Use this command to find where php .so extentions are installed:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;php-config --extension-dir
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;look for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;geos.so&lt;/code&gt; in the folder listed and include this in your zip file&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tar -czvf /app/geos-3.4.2-heroku.tar.gz .heroku/vendor/ `php-config --extension-dir`/geos.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.heroku/php/etc/php/conf.d/geos.ini&lt;/code&gt; with&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;; GEOS extension
extension=geos.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Commit all of this to your local source and push to heroku. NOTE: Everytime PHP is upgraded on heroku you will need to recompile the geos extension. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;php-config --extension-dir&lt;/code&gt; will change with each upgrade as well.&lt;/p&gt;

&lt;h3 id=&quot;links-that-helped-me-figure-all-of-this-out&quot;&gt;Links that helped me figure all of this out:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.petekeen.net/introduction-to-heroku-buildpacks&quot;&gt;http://www.petekeen.net/introduction-to-heroku-buildpacks&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ddollar/heroku-buildpack-multi&quot;&gt;https://github.com/ddollar/heroku-buildpack-multi&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/peterkeen/heroku-buildpack-vendorbinaries&quot;&gt;https://github.com/peterkeen/heroku-buildpack-vendorbinaries&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://joshuaoiknine.com/post/52065881310/compiling-php-extensions-binaries-for-heroku&quot;&gt;http://joshuaoiknine.com/post/52065881310/compiling-php-extensions-binaries-for-heroku&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 12 May 2014 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2014/05/12/run-vendored-binaries-on-heroku.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2014/05/12/run-vendored-binaries-on-heroku.html</guid>
        
        <category>heroku,</category>
        
        <category>devops,</category>
        
        <category>deployment,</category>
        
        <category>joy</category>
        
        
      </item>
    
      <item>
        <title>What to Optimize</title>
        <description>&lt;p&gt;If you hang out with developers enough, you will hear this refrain:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Premature optimization is the root of all evil”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The idea is don’t spend time fixing problems that you don’t have because you are more likely to make your code clumsy and more complicated than it needs to be.&lt;/p&gt;

&lt;p&gt;In my recent work on www.tomnod.com we were hit with a huge amount of traffic during the search for missing Malaysia airlines flight MH370. From that experience, I can tell you that if premature optimization is evil…&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Optimizing under fire is only slightly more fun”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The question becomes what design decisions, which foundations can I lay today, that will let me scale my app to 100x or 1000x the load it handles today. Here is what we learned scaling Tomnod in March of 2014.&lt;/p&gt;

&lt;p&gt;It is never premature to optimize these things:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Create a Productive Error Page&lt;/strong&gt; The page should be static html and javascript. Make sure it never includes hits to the database. This static page lets you provide useful information to the hungry crowd banging on your app’s front door and gives you breathing room. While that page is displayed you are free to do updates and scale the system behind the scenes. Consider it one of the top priority features of your system. Test it in your releases.  Error pages can be useful. An email signup form on our error page (which posted to our SendGrid mailing list) collected email addresses and twitter followers who wanted to be updated as soon as the site was back up and usable. The amount of people who sign up on the error page when our site was “down” amounted to 3x what our entire database of contacts had been before. This made for highly productive downtime and kept our users informed.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Create a Method for Sharding your Users&lt;/strong&gt; During our traffic onslaught, an engineer from Facebook suggested the #1 thing we should do is “hash or shard our users”. By sharding we mean the ability to show a different version of your app to a fraction of users. In our case, needed to bring a bigger database online to support load. We knew the database needed time to warm up its in memory cache. This could only be done with queries to the data. If we had allowed all of our users to hammer the database before the in memory cache was ready, it would have crashed the system. So, we sharded our users. We let 5% of users access the app while the other 95% saw our productive error page. The cache warmed a bit. We then let in 10%… 20%… 50%… 75%… and finally 100% of users. Turns out sharding is useful in other ways.  You can use it to launch and load test new features. Show new feature to x% of users and see if you get bug reports or unexpected load spikes. When things look good with your sample users, then roll the feature out to everyone.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Know Your Outs&lt;/strong&gt; For every component in the system, know and test the next size up. In some cases this might be testing that migrations to the next bigger instance size actually work. In others cases, it might be testing that adding nodes to horizontal worker or web farms works well. Test this frequently. Always make sure you know your next step for each component of your app. Easy to do. Dev environment might be small. Production a bit bigger with more nodes. Moving between them should be push button no crazy deployment hoops to go to larger system.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In sum: with a productive error page, ability to shard users, and by knowing your outs, you should be ready to scale your app to the next order of magnitude. Doing much beyond that might be premature optimization. Doing less might mean a huge lost opportunity when the hungry crowd comes knocking.&lt;/p&gt;
</description>
        <pubDate>Thu, 17 Apr 2014 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2014/04/17/what-to-optimize.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2014/04/17/what-to-optimize.html</guid>
        
        <category>devops</category>
        
        <category>tomnod</category>
        
        <category>high scalability</category>
        
        
      </item>
    
      <item>
        <title>Read More. Code Readability as a Feature.</title>
        <description>&lt;p&gt;Recently I read &lt;a href=&quot;http://www.joelonsoftware.com/articles/fog0000000069.html&quot;&gt;Things You Should Never Do, Part I&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One line really stood out to me:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;It’s harder to read code than to write it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In fact, I think it is &lt;strong&gt;a lot&lt;/strong&gt; harder. I bet that it is at least 10x harder to read and understad code than it is to write it.&lt;/p&gt;

&lt;p&gt;If this is the case, we need to value readability of our code almost just as much as we value it working. Readability is what makes it possible to hand the code to the next developer and have them hit the ground running without having to fight the “let’s just rewrite it urge” so much.&lt;/p&gt;

&lt;p&gt;Code readability might be the key feature to making our projects sustainable.&lt;/p&gt;

&lt;p&gt;Like a paragraph, code can be crafted to be more readable. (Here is the best book I have seen on crafting paragraphs &lt;a href=&quot;http://www.amazon.com/Style-Lessons-Clarity-Grace-Edition/dp/0205747469&quot;&gt;Style: Lessons in Clarity and Grace&lt;/a&gt; )&lt;/p&gt;

&lt;p&gt;My teams are starting to use pull requests and code comments in Github to try to make our code more readable. Pull Requests give other developers on the team a great way to look at changes being made and comment if they do not understand. A side bennifit is that developers reading the code pick up on best practices that others are using and are familliar with others parts of our systems.&lt;/p&gt;

&lt;p&gt;Basic idea for the workflow is: before committing to master, create a pull request. Have someone else read it, comment, understand it and merge with master.&lt;/p&gt;

&lt;p&gt;I will let you know if this improves readabiltiy.&lt;/p&gt;
</description>
        <pubDate>Thu, 17 Apr 2014 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2014/04/17/code-readability-as-a-feature.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2014/04/17/code-readability-as-a-feature.html</guid>
        
        <category>code</category>
        
        <category>design</category>
        
        <category>github</category>
        
        
      </item>
    
      <item>
        <title>Lafayette Teen Tech Week 2014 Hackathon</title>
        <description>&lt;p&gt;I helped teach the hackathon at Lafayette Teen Tech Week.&lt;/p&gt;

&lt;p&gt;The students learned to encrypt and decrypt Ceasar ciphers. The decrypted messages sent them on a scavenger hunt around the Lafayette Public Library.&lt;/p&gt;

&lt;p&gt;Here are some &lt;a href=&quot;http://www.flickr.com/photos/marcrohloff/sets/72157642523591623/&quot;&gt;photos of Lafayette Teen Tech Week 2014&lt;/a&gt;!&lt;/p&gt;

</description>
        <pubDate>Thu, 20 Mar 2014 00:00:00 +0000</pubDate>
        <link>https://www.saintsjd.com/2014/03/20/lafayette-teen-tech-week.html</link>
        <guid isPermaLink="true">https://www.saintsjd.com/2014/03/20/lafayette-teen-tech-week.html</guid>
        
        <category>teaching</category>
        
        
      </item>
    
  </channel>
</rss>
