Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I see a few possible problems. First of all, this:</p> <pre><code>@doc = Nokogiri::XML(sympFile) </code></pre> <p>will slurp the whole XML file into memory as some sort of libxml2 data structure and that will probably be larger than the raw XML file.</p> <p>Then you do things like this:</p> <pre><code>@doc.xpath(...).each </code></pre> <p>That may not be smart enough to produce an enumerator that just maintains a pointer to the internal form of the XML, it might be producing a copy of everything when it builds the <code>NodeSet</code> that <code>xpath</code> returns. That would give you another copy of most of the expanded-in-memory version of the XML. I'm not sure how much copying and array construction happens here but there is room for a fair bit of memory and CPU overhead even if it doesn't copy duplicate everything.</p> <p>Then you make your copy of what you're interested in:</p> <pre><code>symptomsList.push([signId, name]) </code></pre> <p>and finally iterate over that array:</p> <pre><code>symptomsList.each do |x| Symptom.where(:name =&gt; x[1], :signid =&gt; Integer(x[0])).first_or_create end </code></pre> <p>I find that <a href="http://nokogiri.org/Nokogiri/HTML/SAX.html" rel="nofollow">SAX parsers</a> work better with large data sets but they are more cumbersome to work with. You could try creating your own SAX parser something like this:</p> <pre><code>class D &lt; Nokogiri::XML::SAX::Document def start_element(name, attrs = [ ]) if(name == 'DisorderSign') @data = { } elsif(name == 'ClinicalSign') @key = :sign @data[@key] = '' elsif(name == 'SignFreq') @key = :freq @data[@key] = '' elsif(name == 'Name') @in_name = true end end def characters(str) @data[@key] += str if(@key &amp;&amp; @in_name) end def end_element(name, attrs = [ ]) if(name == 'DisorderSign') # Dump @data into the database here. @data = nil elsif(name == 'ClinicalSign') @key = nil elsif(name == 'SignFreq') @key = nil elsif(name == 'Name') @in_name = false end end end </code></pre> <p>The structure should be pretty clear: you watch for the opening of the elements that you're interested in and do a bit of bookkeeping set up when the do, then cache the strings if you're inside an element you care about, and finally clean up and process the data as the elements close. You're database work would replace the</p> <pre><code># Dump @data into the database here. </code></pre> <p>comment.</p> <p>This structure makes it pretty easy to watch for the <code>&lt;Disorder id="17601"&gt;</code> elements so that you can keep track of how far you've gone. That way you can stop and restart the import with some small modifications to your script.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload