<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Robby on Rails: PostgreSQL sequences in Rails</title>
    <link>http://www.robbyonrails.com/articles/2005/08/20/postgresql-sequences-in-rails</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>thoughts.sort_by{|t| t[:topic]}.collect </description>
    <item>
      <title>PostgreSQL sequences in Rails</title>
      <description>&lt;p&gt;Rails doesn&amp;#8217;t support legacy or custom named &lt;a href="http://rubyurl.com/6Wh"&gt;sequences&lt;/a&gt; at the moment. (as far as I am aware). It&amp;#8217;s kind of tricky to have it detect the &lt;code&gt;SEQUENCE&lt;/code&gt; name automatically (every time).&lt;/p&gt;


In &lt;span class="caps"&gt;PHP&lt;/span&gt;, I used this big ugly query to detect this info:
&lt;code&gt;
&lt;pre&gt;
$sql = $db-&amp;gt;prepare("SELECT seq.relname::text
                        FROM pg_class src, pg_class seq, pg_namespace, pg_attribute,
                        pg_depend
                        WHERE
                            pg_depend.refobjsubid = pg_attribute.attnum AND
                            pg_depend.refobjid = src.oid AND
                            seq.oid = pg_depend.objid AND
                            src.relnamespace = pg_namespace.oid AND
                            pg_attribute.attrelid = src.oid AND
                            pg_namespace.nspname = ? AND
                            src.relname = ? AND
                            pg_attribute.attname = ?");
&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;I used this to mimmick the mysql_insert_id function in &lt;span class="caps"&gt;PHP&lt;/span&gt; for PostgreSQL&amp;#8230; ( &lt;a href="http://blog.planetargon.com/archives/29-PHP-pg_insert_id.html"&gt;pg_insert_id&lt;/a&gt; )&lt;/p&gt;


	&lt;p&gt;Well, with Rails, I thought that I would build a similar patch, as the current code just assumes the value would be &lt;code&gt;{column}_id_seq&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;After hours of playing around and thinking that I &lt;a href="http://rubyurl.com/yKc"&gt;figured it all out&lt;/a&gt; ... I decided to run a quick test with a non standard sequence name&amp;#8230; like this one:&lt;/p&gt;


&lt;code&gt;
&lt;pre&gt;
testingdb=# \d legacy.foobar
                                     Table "legacy.foobar" 
  Column   |         Type          |                         Modifiers                          
-----------+-----------------------+------------------------------------------------------------
 foobar_id | integer               | not null default nextval('legacy.old_sequence_name'::text)
 name      | character varying(40) | 
Indexes:
    "foobar_pkey" PRIMARY KEY, btree (foobar_id)

testingdb=# INSERT INTO legacy.foobar (name) VALUES ('abc')
testingdb-# ;
INSERT 17514 1
testingdb=# SELECT * FROM legacy.foobar ;
 foobar_id | name 
-----------+------
       106 | abc
(1 row)
&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;My patch wouldn&amp;#8217;t figure that out because the sequence was not created by &lt;code&gt;SERIAL&lt;/code&gt;. So, my patch started to feel lame and a total waste of time, because I thought that it was fixing a problem.. that works pretty much as effectively as assuming it is &lt;code&gt;_seq&lt;/code&gt;.. but without needing to run a &lt;span class="caps"&gt;SQL&lt;/span&gt; query to determine that. We all (should) know that the field will be named like that when working with &lt;code&gt;SERIAL&lt;/code&gt;. So, my patch didn&amp;#8217;t buy us anything.&lt;/p&gt;


	&lt;p&gt;However, Active Record still doesn&amp;#8217;t support those funky sequence names. So, I found &lt;a href="http://dev.rubyonrails.com/ticket/1273"&gt;this ticket #1273&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Their approach was very similar to what caused me to use my long &lt;span class="caps"&gt;SQL&lt;/span&gt; query in the first place because this was suggested to me well over a year ago and I found it to not work in the following situation.&lt;/p&gt;


	&lt;p&gt;If I have two seperate schemas with the same table name in each like so:&lt;/p&gt;


&lt;code&gt;
&lt;pre&gt;
=# \d legacy.people
                                       Table "legacy.people" 
  Column   |         Type          |                           Modifiers                           
-----------+-----------------------+---------------------------------------------------------------
 people_id | integer               | not null default nextval('legacy.people_people_id_seq'::text)
 name      | character varying(50) | 
Indexes:
    "people_pkey" PRIMARY KEY, btree (people_id)

=# \d foo.people
                                       Table "foo.people" 
  Column   |         Type          |                         Modifiers                          
-----------+-----------------------+------------------------------------------------------------
 people_id | integer               | not null default nextval('foo.people_people_id_seq'::text)
 name      | character varying(50) | 
Indexes:
    "people_pkey" PRIMARY KEY, btree (people_id)      
&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;That patch will not work because you can&amp;#8217;t call the following query:&lt;/p&gt;


&lt;code&gt;
&lt;pre&gt;
# SELECT adsrc FROM pg_attrdef WHERE adrelid = (SELECT oid FROM pg_class WHERE relname = 'people');
ERROR:  more than one row returned by a subquery used as an expression  

&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;... because there are two tables with the same name! (fun, huh?)&lt;/p&gt;


	&lt;p&gt;Mine would work&amp;#8230; but why bother with that huge query? So, I took my ticket out of [PATCH] and decided that I thought it would be best to just assume that sequences are generated with &lt;code&gt;SERIAL&lt;/code&gt; ( &lt;a href="http://rubyurl.com/2W6"&gt;link&lt;/a&gt; ) by default in AR.&lt;/p&gt;


	&lt;p&gt;Okay, so what can we do about custom &lt;code&gt;SEQUENCE&lt;/code&gt; names?&lt;/p&gt;


	&lt;p&gt;Well, I am proposing the following (and mentioned this in the &lt;a href="http://dev.rubyonrails.com/ticket/2016"&gt;ticket #2016&lt;/a&gt;)...&lt;/p&gt;


&lt;code&gt;
&lt;pre&gt;
class LegacyTable &amp;lt; ActiveRecord::Base
  def self.table_name() "legacy.foobar" end

  # new option for this
  set_primary_key "foobar_id", :sequence =&amp;gt; "legacy.old_sequence_name" 
end
&lt;/pre&gt;
&lt;/code&gt;

	&lt;p&gt;(or something along those lines)&lt;/p&gt;


	&lt;p&gt;With this, I can work around these legacy database scenarios with a quick option.  Thoughts/opinions?&lt;/p&gt;


	&lt;p&gt;I decided to post this on my blog as well, because I do know that there are a few skeptical PostgreSQL people out there who read my blog&amp;#8230; I want you to know that I am looking out for you. ;-)&lt;/p&gt;


	&lt;p&gt;I am sick and tired.. and going to sleep now.&lt;/p&gt;
</description>
      <pubDate>Sat, 20 Aug 2005 02:05:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:4a72cbadfe138b7cbdf2195ab44d109c</guid>
      <author>Robby Russell</author>
      <link>http://www.robbyonrails.com/articles/2005/08/20/postgresql-sequences-in-rails</link>
      <category>Ruby on Rails</category>
      <category>Ruby</category>
      <category>PostgreSQL</category>
      <category>activerecord</category>
      <category>postgresql</category>
    </item>
  </channel>
</rss>
