Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #7500 (new defect)

Opened 2 years ago

Last modified 5 months ago

[PATCH] null cannot be archived in CSV fixtures

Reported by: yssk22 Assigned to: bitsweat
Priority: normal Milestone: 2.x
Component: ActiveRecord Version: edge
Severity: normal Keywords: fixtures
Cc: chuyeow

Description

I made a following csv fixture and executed insertion test, but it failed.

(in ACTIVE_RECORD/test/fixtures/csv/topics.csv)
id,title,author_name,author_email_address,written_on,bonus_time,last_read,content,approved,replies_count,parent_id,type,
1,The First Topic,David,david@loudthinking.com,2003-07-16 15:28:11,2005-01-30 15:28:00,2004/4/15,Have a nice day,0,1,,
2,The Second Topic's of the day,Mary,,2003-07-15 15:28:00,,,Have a nice day,1,0,1,Replay
(in ACTIVE_RECORD/test/fixtures_test.rb)
  def test_csv_inserts
    topics = create_fixtures("csv/topics")
    firstRow = ActiveRecord::Base.connection.select_one("SELECT * FROM topics WHERE author_name = 'David'")
    assert_equal("The First Topic", firstRow["title"])

    secondRow = ActiveRecord::Base.connection.select_one("SELECT * FROM topics WHERE author_name = 'Mary'")
    assert_nil(secondRow["author_email_address"])    
  end
(test result)
  1) Error:
test_csv_inserts(FixturesTest):
ActiveRecord::StatementInvalid: Mysql::Error: #22003Out of range value adjusted
for column 'parent_id' at row 1: INSERT INTO topics (`author_name`, `title`, `type`, `approved`, `id`, `replies_count`, `bonus_time`, `content`, `written_on`, `author_email_address`, `parent_id`, `last_read`) VALUES ('David', 'The First Topic', '', '0', '1', '1', '2005-01-30 15:28:00', 'Have a nice day', '2003-07-16 15:28:11', 'david@loudthinking.com', '', '2004/4/15')

In the rails guide (http://manuals.rubyonrails.com/read/chapter/26#page65), it is said,

nulls can be achived by just placing a comma, for example, (1,sclaus,,false,) minus the parenthesis of course.

but an emtpy cell seems to be archived as an empty string.

I attach the fixtures.rb patch for this issue to be resolved.

Attachments

fixtures_csv_empty_cell_as_null.patch (0.6 kB) - added by yssk22 on 02/06/07 15:20:36.
null_csv_values_tests2.diff (1.3 kB) - added by moofbong on 06/05/07 20:22:38.
Test case

Change History

02/06/07 15:20:36 changed by yssk22

  • attachment fixtures_csv_empty_cell_as_null.patch added.

05/09/07 09:57:40 changed by chuyeow

  • cc set to chuyeow.
  • owner changed from core to bitsweat.

#4157 describes the same problem. Basically, the current CSV fixture reader method in fixtures.rb tries to insert an empty string instead of nil (NULL) in cases where the cell is empty (as yssk22 described above). This patch should fix things just right.

I'm gonna assign this to Mr. bitsweat just because he's the last guy who worked on this file (and you checked in my last unsolicited ticket assignment!) ;)

06/05/07 20:22:38 changed by moofbong

  • attachment null_csv_values_tests2.diff added.

Test case

06/05/07 20:23:53 changed by moofbong

I added a test case patch (also added to #4157) that illustrates this bug.

(follow-ups: ↓ 4 ↓ 6 ) 06/20/07 21:54:35 changed by ajitdsa

this change actually appears to be incorrect. shouldn't it be more like this?

row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.nil? ? nil : cell.to_s.strip }

if you test for blank, then you are essentially setting null cells to blank. this is especially prevalent in non-string fields (i.e. integers) where you want to allow NULLs.

i just ran into this is my project, and then make this change, and it worked just fine. however, this means the CSV file should look like this:

id,integer,string 1"" 2 3,0,""

in the above case: row1: id=1, integer=NULL, string="" row2: id=2, integer=NULL, string=NULL row3: id=3, integer=0, string=""

(in reply to: ↑ 3 ) 09/12/07 02:15:45 changed by mla

ajitdsa's modification is correct. Just tried it and it fixed the problem for me.

03/18/08 03:29:24 changed by pauldoerwald

+1

(in reply to: ↑ 3 ) 03/30/08 20:19:45 changed by =mike

Replying to ajitdsa:

row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.nil? ? nil : cell.to_s.strip }

+1 This fixes the problem in my tests in Rails 1.2.3 and 2.0.2