Feature Requests: Browse | Submit New | Admin

[#29715] Add support for SCHEMA.TABLE_NAME table names

Date:
2013-02-20 21:47
Priority:
3
Submitted By:
Nathan Wiebe (nwiebe)
Assigned To:
Praveen Devarao (praveend)
Category:
Rails adapter
State:
Open
Summary:
Add support for SCHEMA.TABLE_NAME table names

Detailed description
I just went though the process of adding support for SCHEMA.TABLE_NAME to the v2.5.11 of the driver for our internal
use.  This modification is essential for us.  We're running a rails app against a database with hundreds of tables in
different schemas.

I'd appreciate it if we could specify table names like:

class SomeTableInASchema < ActiveRecord::Base
  self.table_name = 'schema1.some_table'
end

class AnotherTableInASchema < ActiveRecord::Base
  self.table_name = 'schema2.other_table'
end

It's not a big modification but it would be nice if it was supported out of the box.

Add A Comment: Notepad

Please login


Followup

Message
Date: 2013-02-27 21:35
Sender: Nathan Wiebe

First create a new database (db2 v9.7.4 on Linux/Windows):
>db2 create database ibmdbex
	
Now create some tables with 1 row each:
>create table schema1.table1 (
  id integer,
  name1 varchar(100),
  description1 varchar(255)
);
>insert into schema1.table1 (name1, 
description1)values('test1', 'this is a test1');

>create table schema2.table2 (
  id integer,
  name2 varchar(100),
  description2 varchar(255)
);
insert into schema2.table2 (name2, 
description2)values('test2', 'this is a test2');

create a new rails (v3.1.12) app:
>mkdir ibmdbex
>cd ibmdbex
>rails new .

Add ibm_db to Gemfile.
>bundle install

Setup a dev environment in config/database.yml, specifing 
the schema to match schema1.table1 above:
development:
  adapter: ibm_db
  database: ibmdbex
  host: 127.0.0.1
  username: user
  password: secret
  schema: schema1
  
Now define two models, one with the same schema as specified 
in config/database.yml (Table1) and other other not 
(Table2):

app/models/table1.rb:
class Table1 < ActiveRecord::Base
  self.table_name = 'table1' #table in schema specified in 
database.yml
end

app/models/table2.rb:
class Table2 < ActiveRecord::Base
  self.table_name = 'schema2.table2' #table NOT in schema 
specified in database.yml
end

Now get into the rails console and see what the models know 
about the columns in their backing tables:
---
rails c
irb(main):007:0> Table1.columns
=> [#
<ActiveRecord::ConnectionAdapters::IBM_DBColumn:0x3a62930 
@name="id", @sql_type="integer", @null=true,
@limit=nil,
@precision=nil, @scale=nil, @type=:integer, @default=nil, 
@primary=false, @coder=nil>, #<Ac
tiveRecord::ConnectionAdapters::IBM_DBColumn:0x3a61fe8 
@name="name1", @sql_type="varchar(100)",
@null=true,
@limit=100, @precision=nil, @scale=nil, @type=:string, 
@default=nil, @primary=false, @coder=nil>, #<Act
iveRecord::ConnectionAdapters::IBM_DBColumn:0x3a61fa0 
@name="description1", @sql_type="varchar(255)",
@null=true,
@limit=255, @precision=nil, @scale=nil, @type=:string, 
@default=nil, @primary=false, @coder=nil>]

irb(main):008:0> Table2.columns
=> []
---

As you can see from the above, the columns for Table1 are 
known, but not Table2.
Similarly, .arel_table doesn't know about any columns in 
Table2, even saying that Table2 doesn't exist.

---
irb(main):001:0> Table1.arel_table
=> #<Arel::Table:0x3b37a38 @name="table1", 
@engine=Table1(id: integer, name1: string, description1: 
string), @columns=nil, @aliases=[], @table_alias=nil, 
@primary_key=nil>
irb(main):002:0> Table2.arel_table
=> #<Arel::Table:0x4ca1138 @name="schema2.table2",
@engine=Table2(Table doesn't exist), @columns=nil, @aliases=
[], @table_alias=nil, @primary_key=nil>
---

Table2's lack of column knowledge can be seen when using the 
arel .where selector.  In the example below notice that 
Table1 knows it's columns, but table 2 does not.

rails c
---
irb(main):003:0> Table1.where(name1: 'test1')
   [1m?[35mTable1 Load (5.0ms)?[0m  SELECT table1.* FROM 
table1 WHERE table1.name1 = 'test1'
=> [#<Table1 id: nil, name1: "test1", description1:
"this is
a test1">]
irb(main):004:0> Table2.where(name2: 'test2')
   [1m?[36mTable2 Load (6.0ms)?[0m  ?[1mSELECT 
schema2.table2.* FROM schema2.table2 WHERE 
schema2.table2.name2 = 'test2' ?[0m
=> [#<Table2 >]
---

This lack of knowledge also affects things like casting DB2 
DATE columns to ruby Date instances on SQL selects, and vice 
versa on SQL inserts.

Thanks for your interest.  I hope I've made myself more 
clear, let me know if you'd like more detail.

Nathan
Date: 2013-02-23 14:42
Sender: Praveen Devarao

Hi Nathan,

Could you elaborate on the requirement. When you say support
in the adapter do you mean. The adapter should be able to parse
the table name and if it has the 2 part naming be able to treat
the first name as schema name?

An illustartion with example would be handy.

Thanks

Praveen

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

Field Old Value Date By
assigned_tonone2013-02-23 14:42praveend