سؤال

أنا أستخدم JRURY والقضبان 2.2.2. مشكلتي هل لدي هجرة غير مكتوبة بشكل صحيح إلى مخطط قاعدة البيانات.

هنا هو هجرتي:

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

هنا هو ما ينتج عنه في schema.rb

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"

لدي سؤالان:

  • كيف أحصل 'ENGINE=MyISAM' في المخطط؟
  • لماذا أصبح بيان تنفيذي add_index "notes", ["title", "body"], :name => "title"ب وكيف أجبر الهجرة على تركها كبيان تنفيذ؟

بفضل المسيحي Lescuyer للإجابة. ومع ذلك، عندما حاولت هذا لم يتغير شيء. أنا unceded config.active_record ... سطر ولكن، لم يتغير مخططي. لقد جربت هذا في JRURY وعلى روبي 1.8.6 مع القضبان 2.2.2 وقضبان الحافة وليس هناك تغييرات في المخطط. هل يمكن لأحد أن يقول لي ما أفعله خطأ؟

هل كانت مفيدة؟

المحلول

مع استخدام قيود المفاتيح الأجنبية، استخدم تنسيق SQL للترحيل. في البيئة:

# 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

نصائح أخرى

أنا أيضا من المتوقع أن أرى ملف .sql جديد يظهر بعد "أشعل النار DB: ترحيل"، بمجرد ضبط

config.active_record.schema_format = :sql

في التكوين / البيئة.

يبدو أن هذا ليس كيف يعمل، ولكن. يجب أن أفعل هذا صراحة للحصول على DB / [تطوير | اختبار | الإنتاج] _STRYURE.SQL ملف:

rake db:structure:dump

مجرد تحديث لأولئك على القضبان 3 (بيتا 4، حاليا) - لا يزال حل المسيحي صحيحة، فقط المكان الصحيح لوضع الخط في config/application.rb, ، تحت نطاق Application الطبقة التي يجب تعريفها في وحدة نمطية باسم مشروع القضبان الخاصة بك.

المسيحي هو الصحيح.

فعل

config.active_record.schema_format =: SQL

في البيئة

ولكن بعد ذلك، يجب عليك استخدام تنسيق تفريغ مخطط مختلف وموقع ملف. حاول القيام برحلاتك وتبحث عن "schema.sql" بدلا من scehema.rb

سبب كل هذا هو أن نقطة ملف المخطط هي قاعدة بيانات غير محددة (يعمل لجميع أنواع قواعد البيانات) ملف. لذلك عند استخدام الميزات التي تعمل فقط على MySQL من خلال عبارة تنفيذ غير مسبوقة، لا يمكن تحمله في SHEMA.RB

لاستخدام متغير SQL للاختبار (بدلا من schema.rb)، ستحتاج إلى استخدام

أشعل النار DB: اختبار: Clone_Sulture

يستخدم مخططنا Uuids (GEM UUID) وأيضا أحمر التل على القضبان (rhor) المكون الإضافي FK لطيف. لسوء الحظ، تتطلب FKS PKs التي لا يمكن إضافتها إلا باستخدام Executes في الترحيل.

من المعروف أن هذه تنفذ لا تجعله إلى Schema.rb؛ ومع ذلك، كان من الصعب العثور على بديل أشعل النار ل DB: اختبار: الاستعداد للتطبيقات التي لا يمكن استخدام schema.rb.

يحل MonkePatch التالية من مشكلة فهرس الفهرس مؤقتا وخيار محرك DB لمخطط الخاص بك (القضبان 3.2). يمكنك وضعه في config/initializers/ (على سبيل المثال 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
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top