2008-12-20 23 views
10

Jruby ve rayları kullanıyorum 2.2.2. Sorunum, veritabanı şemasına doğru yazılmayan bir geçişim var.Raylar Şema oluşturma sorunu

  • nasıl içine 'ENGINE=MyISAM' alabilirim:

    İşte
    class CreateNotes < ActiveRecord::Migration 
        def self.up 
        create_table(:notes, :options => 'ENGINE=MyISAM') do |t| 
         t.string :title 
         t.text :body 
    
         t.timestamps 
        end 
    
        execute "alter table notes ADD FULLTEXT(title, body)" 
    
    end 
    

    ben iki sorum var

    create_table "notes", :force => true do |t| 
        t.string "title" 
        t.text  "body" 
        t.datetime "created_at" 
        t.datetime "updated_at" 
    end 
    
    add_index "notes", ["title", "body"], :name => "title" 
    

    schema.rb üzerinde üretir budur: İşte

    benim göç şema?
  • Neden yürütme ifadem add_index "notes", ["title", "body"], :name => "title" oldu? ve geçişleri bir yürütme ifadesi olarak bırakacak şekilde nasıl zorlayabilirim?

Yanıt için Christian Lescuyer'a teşekkürler. Ancak, denediğimde hiçbir şey değişmedi. Config.active_record ... satırını beğenmedim ancak şemam değişmedi. Bunu jruby'de ve 1.8.6 rubi ile ray 2.2.2 ve kenar rayları ile denedim ve şemada değişiklik yok. Bana yanlış ne yaptığımı söyleyen var mı? Yabancı anahtar kısıtlamalarını kullandığımdan, geçişler için SQL biçimini kullanıyorum.

+0

Eğer schema.rb sildiniz mi? Bunun yerine bir .sql dosyası almalısınız, ancak eski schema.rb'nin hala etrafta olduğunu düşünüyorum. –

cevap

8

environment.rb yılında:

# Use SQL instead of Active Record's schema dumper when creating the test database. 
# This is necessary if your schema can't be completely dumped by the schema dumper, 
# like if you have constraints or database-specific column types 
config.active_record.schema_format = :sql 
1

hıristiyan haklı.

yapmak

config.active_record.schema_format =: sql

environment.rb

ama o zaman farklı bir şema dökümü formatı ve dosya konumunu kullanmak zorunda içinde. geçişi yapmayı deneyin ve scehema.rb yerine "schema.sql" ifadesini arıyoruz. Bunun nedeni, şema dosyasının noktasının (her çeşit veritabanında çalışır) dosyaya özgü olmayan bir veritabanı olmasıdır. mysql üzerinde bir unsupoorted execute deyimi üzerinde çalışan özellikleri kullandığınızda, bunlar schema.rb

10

için yeni bir .sql dosyasının "rake db: migrate" ifadesinden sonra görünmesini beklemeden Bir kez config/environment.rb dosyasında

'u ayarladıktan sonra. Bununla birlikte, görünüşe göre böyle değil. [| Test | gelişimini üretim] Bir db/almak için açıkça bunu yapmak zorunda _structure.sql dosyasını:

rake db:structure:dump 
+0

Bir rake yapmak db: test: otomatik olarak bir db hazırlayacaktır: yapı: geliştirme veritabanından döküm ve sonra bir db: yapı: schema_format ayarlandığında test veritabanına yüklenir: sql –

1

(yerine schema.rb ait) testleri için SQL varyantını kullanmak için gerekir

tırmık db kullanın: Test: clone_structure

Bizim şema UUIDs (uuid mücevher) ve 'Kırmızı Tepesi Raylar (RHoR) güzel FK eklentisi üzerinde kullanır. Ne yazık ki, FK'ler sadece geçişlerde EXECUTES kullanılarak eklenebilecek PK'lere ihtiyaç duyarlar.

Bu yürütmelerin schema.rb'ye yapamadıkları iyi bilinir; Ancak, db: tırma tırmık alternatifini bulmak daha zordu: schema.rb kullanamayan uygulamalar için hazırlanın.

6

Sadece Rails 3 (beta 4, şu anda) ile ilgili bir güncelleme - Christian'ın çözümü hala doğru, satırın konulacağı doğru yer olan Application dersinin kapsamı altında olması gereken satırın config/application.rb sınıfında olması yeterlidir. Rails projenizin adını alan modül.

+1

Simgenizdeki güzel DHH saçları – gtd

1

Aşağıdaki monkeypatch, şema damperinizin (Rails 3.2) hem FULLTEXT dizini hem de DB motoru seçeneğini çözer. İçeri koyabilirsiniz config/initializers/ (örn schema_dumper_monkeypatch.rb):

module ActiveRecord 
    class SchemaDumper 
    def table(table, stream) 
     columns = @connection.columns(table) 
     begin 
     tbl = StringIO.new 

     # first dump primary key column 
     if @connection.respond_to?(:pk_and_sequence_for) 
      pk, _ = @connection.pk_and_sequence_for(table) 
     elsif @connection.respond_to?(:primary_key) 
      pk = @connection.primary_key(table) 
     end 

     tbl.print " create_table #{remove_prefix_and_suffix(table).inspect}" 
     if columns.detect { |c| c.name == pk } 
      if pk != 'id' 
      tbl.print %Q(, :primary_key => "#{pk}") 
      end 
     else 
      tbl.print ", :id => false" 
     end 
     tbl.print ", :force => true" 

     # Add table engine 
     res = @connection.execute "SHOW TABLE STATUS LIKE '#{table}'" 
     engine = res.first[res.fields.index("Engine")] rescue nil 
     tbl.print ", :options => 'ENGINE=#{engine}'" if engine 
     res = nil # Free the result   

     tbl.puts " do |t|" 

     # then dump all non-primary key columns 
     column_specs = columns.map do |column| 
      raise StandardError, "Unknown type '#{column.sql_type}' for column '#{column.name}'" if @types[column.type].nil? 
      next if column.name == pk 
      spec = {} 
      spec[:name]  = column.name.inspect 

      # AR has an optimization which handles zero-scale decimals as integers. This 
      # code ensures that the dumper still dumps the column as a decimal. 
      spec[:type]  = if column.type == :integer && [/^numeric/, /^decimal/].any? { |e| e.match(column.sql_type) } 
           'decimal' 
          else 
           column.type.to_s 
          end 
      spec[:limit]  = column.limit.inspect if column.limit != @types[column.type][:limit] && spec[:type] != 'decimal' 
      spec[:precision] = column.precision.inspect if column.precision 
      spec[:scale]  = column.scale.inspect if column.scale 
      spec[:null]  = 'false' unless column.null 
      spec[:default] = default_string(column.default) if column.has_default? 
      (spec.keys - [:name, :type]).each{ |k| spec[k].insert(0, "#{k.inspect} => ")} 
      spec 
     end.compact 

     # find all migration keys used in this table 
     keys = [:name, :limit, :precision, :scale, :default, :null] & column_specs.map{ |k| k.keys }.flatten 

     # figure out the lengths for each column based on above keys 
     lengths = keys.map{ |key| column_specs.map{ |spec| spec[key] ? spec[key].length + 2 : 0 }.max } 

     # the string we're going to sprintf our values against, with standardized column widths 
     format_string = lengths.map{ |len| "%-#{len}s" } 

     # find the max length for the 'type' column, which is special 
     type_length = column_specs.map{ |column| column[:type].length }.max 

     # add column type definition to our format string 
     format_string.unshift " t.%-#{type_length}s " 

     format_string *= '' 

     column_specs.each do |colspec| 
      values = keys.zip(lengths).map{ |key, len| colspec.key?(key) ? colspec[key] + ", " : " " * len } 
      values.unshift colspec[:type] 
      tbl.print((format_string % values).gsub(/,\s*$/, '')) 
      tbl.puts 
     end 

     tbl.puts " end" 
     tbl.puts 

     indexes(table, tbl) 

     tbl.rewind 
     stream.print tbl.read 
     rescue => e 
     stream.puts "# Could not dump table #{table.inspect} because of following #{e.class}" 
     stream.puts "# #{e.message}" 
     stream.puts 
     end 

     stream 
    end  

    def indexes(table, stream) 
     if (indexes = @connection.indexes(table)).any? 
     add_index_statements = indexes.map do |index| 

      if index.name =~ /fulltext/i 
      " execute \"CREATE FULLTEXT INDEX #{index.name} ON #{index.table} (#{index.columns.join(',')})\"" 
      elsif index.name =~ /spatial/i 
      " execute \"CREATE SPATIAL INDEX #{index.name} ON #{index.table} (#{index.columns.join(',')})\"" 
      else 
      statement_parts = [ 
       ('add_index ' + remove_prefix_and_suffix(index.table).inspect), 
       index.columns.inspect, 
       (':name => ' + index.name.inspect), 
      ] 
      statement_parts << ':unique => true' if index.unique 

      index_lengths = (index.lengths || []).compact 
      statement_parts << (':length => ' + Hash[index.columns.zip(index.lengths)].inspect) unless index_lengths.empty? 

      index_orders = (index.orders || {}) 
      statement_parts << (':order => ' + index.orders.inspect) unless index_orders.empty? 

      ' ' + statement_parts.join(', ') 
      end 
     end 

     stream.puts add_index_statements.sort.join("\n") 
     stream.puts 
     end 
    end 
    end 
end 
İlgili konular