রেলগুলি ব্যবহার করে, আমি কীভাবে আমার প্রাথমিক কীটি পূর্ণসংখ্যা-টাইপযুক্ত কলামটি না সেট করতে পারি?


86

আমি একটি ডেটাবেস স্কিমা পরিচালনা করতে রেল মাইগ্রেশন ব্যবহার করছি এবং আমি একটি সাধারণ টেবিল তৈরি করছি যেখানে আমি প্রাথমিক কী হিসাবে (বিশেষত স্ট্রিং) নন-ইন্টিজার মানটি ব্যবহার করতে চাই। আমার সমস্যা থেকে দূরে সরে যেতে, আসুন আমরা বলতে পারি যে একটি টেবিল রয়েছে employeesযেখানে কর্মীরা একটি বর্ণানুক্রমিক স্ট্রিং দ্বারা চিহ্নিত করা হয়, যেমন "134SNW"

আমি এইভাবে মাইগ্রেশনে টেবিল তৈরি করার চেষ্টা করেছি:

create_table :employees, {:primary_key => :emp_id} do |t|
    t.string :emp_id
    t.string :first_name
    t.string :last_name
end

এটি আমাকে যা দেয় তা হ'ল এটি সম্পূর্ণরূপে লাইনটিকে উপেক্ষা করে t.string :emp_idএগিয়ে যায় এবং এটি একটি পূর্ণসংখ্যা কলাম তৈরি করে। কোনও executeকলটিতে এসকিউএল না লিখে, রেলগুলি আমার জন্য PRIMARY_KEY সীমাবদ্ধতা (আমি PostgreSQL ব্যবহার করছি) তৈরি করার অন্য কোনও উপায় আছে কি ?

দ্রষ্টব্য : আমি জানি প্রাথমিক কী হিসাবে স্ট্রিং কলামগুলি ব্যবহার করা ভাল নয়, সুতরাং দয়া করে কোনও উত্তরই কেবল পূর্ণসংখ্যার প্রাথমিক কী যুক্ত করার কথা বলছে না। আমি যাইহোক একটি যোগ করতে পারেন, তবে এই প্রশ্নটি এখনও বৈধ।


আমার একই সমস্যা আছে এবং আমি এর উত্তর দেখতে পছন্দ করব। এখনও অবধি কোনও পরামর্শই কাজ করেনি।
শান ম্যাকক্লেয়ারি

4
আপনি পোস্টগ্র্রেস ব্যবহার করলে তাদের কেউই কাজ করবে না। ড্যান চাকের "এন্টারপ্রাইজ রেলস" এর প্রাকৃতিক / সংমিশ্রিত কীগুলি ব্যবহারের জন্য কিছু টিপস রয়েছে।
আজিম.বাট

আপনি যখন এই জাতীয় কিছু ব্যবহার করেন তখন সাবধান হন: <! - ভাষা: ল্যাং-আরবি -> "প্রাথমিক কী কর্মী (এমপি_আইডি) যোগ করুন" যদিও চলার পরে টেবিলের সীমাবদ্ধতাটি সঠিকভাবে সেট করা আছে rake db:migrateস্বয়ংক্রিয়ভাবে উত্পন্ন স্কিমা সংজ্ঞাটিতে এই সীমাবদ্ধতা নেই!
পিমকিন

উত্তর:


107

দুর্ভাগ্যক্রমে, আমি নির্ধারণ করেছি যে এটি ব্যবহার না করে এটি করা সম্ভব নয় execute

কেন এটি কাজ করে না

অ্যাক্টিভেকর্ড উত্স পরীক্ষা করে, আমরা এর জন্য কোডটি খুঁজে পেতে পারি create_table:

ইন schema_statements.rb:

def create_table(table_name, options={})
  ...
  table_definition.primary_key(options[:primary_key] || Base.get_primary_key(table_name.to_s.singularize)) unless options[:id] == false
  ...
end

সুতরাং আমরা দেখতে পাচ্ছি যে আপনি যখন বিকল্পগুলিতে একটি প্রাথমিক কী নির্দিষ্ট করার চেষ্টা করেন create_table, তখন এটি নির্দিষ্ট নামের (বা, যদি কোনওটি নির্দিষ্ট না করা হয় id) দিয়ে একটি প্রাথমিক কী তৈরি করে । এটা একই পদ্ধতি একটি টেবিল সংজ্ঞা ব্লক ভিতরে ব্যবহার করতে পারেন কল করে এই আছে: primary_key

ইন schema_statements.rb:

def primary_key(name)
  column(name, :primary_key)
end

এটি কেবল প্রকারের নির্দিষ্ট নাম সহ একটি কলাম তৈরি করে :primary_key। এটি স্ট্যান্ডার্ড ডাটাবেস অ্যাডাপ্টারগুলিতে নিম্নলিখিতটিতে সেট করা আছে:

PostgreSQL: "serial primary key"
MySQL: "int(11) DEFAULT NULL auto_increment PRIMARY KEY"
SQLite: "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"

কর্মক্ষেত্রের

যেহেতু আমরা এগুলিকে প্রাথমিক কী ধরণের হিসাবে আটকে আছি, তাই আমাদের executeএকটি প্রাথমিক কী তৈরি করতে ব্যবহার করতে হবে যা কোনও পূর্ণসংখ্যা নয় (পোস্টগ্র্যাস এসকিউএল এর serialএকটি ক্রম ব্যবহার করে একটি পূর্ণসংখ্যা):

create_table :employees, {:id => false} do |t|
  t.string :emp_id
  t.string :first_name
  t.string :last_name
end
execute "ALTER TABLE employees ADD PRIMARY KEY (emp_id);"

এবং শন ম্যাকক্লিয়ারি যেমন উল্লেখ করেছেন , আপনার অ্যাক্টিভেকর্ড মডেলটির সাহায্যে প্রাথমিক কীটি সেট করা উচিত set_primary_key:

class Employee < ActiveRecord::Base
  set_primary_key :emp_id
  ...
end

15
কর্মক্ষেত্রটি রেক ডিবি তৈরি করবে: পরীক্ষা: ক্লোন বা রেক ডিবি: স্কিমা: পূর্ণসংখ্যা কলাম হিসাবে এমপ_আইডি তৈরি করতে লোড।
ডনি করনিয়া

18
প্রকৃতপক্ষে, এখন আপনার self.primary_key=পরিবর্তে ব্যবহার করা উচিত set_primary_key, যেহেতু পরেরটি অবচিত হয়।
গ্যারি এস ওয়েভার

4
এখানে আমার জন্য কাজ করা একমাত্র সমাধান। আমি আশা করি এটা অন্যদের সাহায্য: stackoverflow.com/a/15297616/679628
findchris

8
এই পদ্ধতির সাথে সমস্যা হ'ল আপনি যখন থেকে আপনার ডাটাবেস সেটআপ করবেন তখন আবার টাইপ কলাম schema.rb emp_idহবে integer। দেখে মনে হচ্ছে এটি কোনওভাবেই schema.rbসঞ্চয় করতে পারে না execute "ALTER TABLE employees ADD PRIMARY KEY (emp_id);"
টিনটিন 8১

4
@DonnyKurnia @ Tintin81 আপনি থেকে স্কিমা ডাম্প সুইচ করতে পারেন schema.rbকরার structure.sqlমাধ্যমে config.active_record.schema_formatসেটিংটির প্রয়োজন, যা হতে পারে পারেন :sqlবা :rubyগাইড.আরবিওনরাইলস.আর.ভি.ভি.২.২৩৩
ইভানোভ

21

এইটা কাজ করে:

create_table :employees, :primary_key => :emp_id do |t|
  t.string :first_name
  t.string :last_name
end
change_column :employees, :emp_id, :string

এটি সুন্দর নাও হতে পারে তবে শেষের ফলাফলটি আপনি যা চান ঠিক তেমন হয়।


4
অবশেষে! এটি আমার জন্য কাজ করা একমাত্র সমাধান।
Findchris

আমাদেরও কি স্থানান্তরের জন্য কোডটি নীচে উল্লেখ করতে হবে? বা রেলগুলি যথেষ্ট স্মার্ট হয় যে স্থানান্তরিত হওয়ার পরে কী করতে হবে?
amey1908

4
ডাউন মাইগ্রেশনের জন্য:drop_table :employees
অস্টিন

6
দুর্ভাগ্যক্রমে, এই পদ্ধতিটি আমাদের এমন একটি ছেড়ে দেয় যা schema.rbসিঙ্কে নেই ... এটি :primary_key => :emp_idঘোষণাটি ধরে রাখবে , কিন্তু যখন rake db:schema:loadএটি ডাকা হয়, যখন এটি পরীক্ষার শুরুতে হয়, এটি একটি পূর্ণসংখ্যা কলাম তৈরি করবে। তবে, এটি এমন পরিস্থিতিতে হতে পারে যে আপনি যদি structure.sql(কনফিগারেশন বিকল্প) পরীক্ষাগুলি ব্যবহার করে স্যুইচাটি লোড করার জন্য সেটিংস ধরে রাখেন এবং সেই ফাইলটি ব্যবহার করবেন।
টম হ্যারিসন

18

আমার এটি পরিচালনা করার একটি উপায় আছে। কার্যকর করা এসকিউএল হ'ল এএনএসআই এসকিউএল তাই এটি সম্ভবত বেশিরভাগ এএনএসআই এসকিউএল অনুগত রিলেশনাল ডাটাবেসগুলিতে কাজ করবে। আমি পরীক্ষা করেছি যে এটি মাইএসকিউএল এর জন্য কাজ করে।

মাইগ্রেশন:

create_table :users, :id => false do |t|
    t.string :oid, :limit => 10, :null => false
    ...
end
execute "ALTER TABLE users ADD PRIMARY KEY (oid);"

আপনার মডেলটিতে এটি করুন:

class User < ActiveRecord::Base
    set_primary_key :oid
    ...
end


10

5 কারাগারে আপনি করতে পারেন

create_table :employees, id: :string do |t|
  t.string :first_name
  t.string :last_name
end

Create_table ডকুমেন্টেশন দেখুন ।


before_create :set_idপ্রাথমিক কীটির মান নির্ধারণ করার জন্য আপনাকে মডেলটিতে কিছু প্রকারের পদ্ধতি যুক্ত করতে হবে
ফ্লোটিংআরক

9

আমি এটি 4.2 রেলগুলিতে চেষ্টা করেছি। আপনার কাস্টম প্রাথমিক কী যুক্ত করতে আপনি নিজের স্থানান্তরটি এইভাবে লিখতে পারেন:

# tracks_ migration
class CreateTracks < ActiveRecord::Migration
  def change
    create_table :tracks, :id => false do |t|
      t.primary_key :apple_id, :string, limit: 8
      t.string :artist
      t.string :label
      t.string :isrc
      t.string :vendor_id
      t.string :vendor_offer_code

      t.timestamps null: false
    end
    add_index :tracks, :label
  end
end

ডকুমেন্টেশন column(name, type, options = {})এবং লাইন পড়ার সময়:

type: Primary_key,: স্ট্রিং,: পাঠ্য: পূর্ণসংখ্যা: ভাসা: দশমিক,: DATETIME: সময়,: তারিখ: বাইনারি: প্যারামিটার স্বাভাবিকভাবে মাইগ্রেশন নেটিভ ধরনের, নিম্নলিখিত এক অন্যতম বুলিয়ান ।

আমি যেমন দেখিয়েছি তেমন উপরের অংশগুলি পেয়েছি। এই স্থানান্তরটি চালনার পরে টেবিল মেটা ডেটা এখানে রয়েছে:

[arup@music_track (master)]$ rails db
psql (9.2.7)
Type "help" for help.

music_track_development=# \d tracks
                    Table "public.tracks"
      Column       |            Type             | Modifiers
-------------------+-----------------------------+-----------
 apple_id          | character varying(8)        | not null
 artist            | character varying           |
 label             | character varying           |
 isrc              | character varying           |
 vendor_id         | character varying           |
 vendor_offer_code | character varying           |
 created_at        | timestamp without time zone | not null
 updated_at        | timestamp without time zone | not null
 title             | character varying           |
Indexes:
    "tracks_pkey" PRIMARY KEY, btree (apple_id)
    "index_tracks_on_label" btree (label)

music_track_development=#

এবং রেলস কনসোল থেকে:

Loading development environment (Rails 4.2.1)
=> Unable to load pry
>> Track.primary_key
=> "apple_id"
>>

4
সমস্যাটি আসে, তবে যে schema.rbফাইলটি উত্পন্ন হয় তা stringপ্রাথমিক কীটির প্রকারটি প্রতিফলিত করে না , সুতরাং একটি দিয়ে ডাটাবেস তৈরি করার সময় load, প্রাথমিক কীটি পূর্ণসংখ্যা হিসাবে তৈরি হয়।
পিটার আলফভিন

8

দেখে মনে হচ্ছে এই পদ্ধতির ব্যবহার করে এটি করা সম্ভব:

create_table :widgets, :id => false do |t|
  t.string :widget_id, :limit => 20, :primary => true

  # other column definitions
end

class Widget < ActiveRecord::Base
  set_primary_key "widget_id"
end

এটি উইজেট শ্রেণীর জন্য কলামটি উইজেট_আইডিকে প্রাথমিক কী হিসাবে তৈরি করবে, তারপরে অবজেক্ট তৈরি হওয়ার পরে ক্ষেত্রটি পপুলেশন করা আপনার পক্ষে হবে। কলব্যাক তৈরি করার আগে আপনি এটি ব্যবহার করে সক্ষম হবেন।

তাই লাইন বরাবর কিছু

class Widget < ActiveRecord::Base
  set_primary_key "widget_id"

  before_create :init_widget_id

  private
  def init_widget_id
    self.widget_id = generate_widget_id
    # generate_widget_id represents whatever logic you are using to generate a unique id
  end
end

এটি আমার পক্ষে কাজ করে না, অন্তত পোস্টগ্র্যাস এসকিউএলে নয়। কোনও প্রাথমিক কী মোটেই নির্দিষ্ট করা হয়নি।
রুড জুইলিনস্কি

হুম মজার আকর্ষণীয় আমি মাইএসকিউএল দিয়ে এটি ২.৩.২ রেলে পরীক্ষা করেছি - খুব সম্ভবত রেলের সংস্করণ সম্পর্কিত হতে পারে?
পোল্টেনার্ড

আমি নিশ্চিত নই - আমি মনে করি না এটি রেলগুলির সংস্করণ। আমি রেলগুলি ২.৩.৩ ব্যবহার করছি।
রুড জওলিনস্কি

দুর্ভাগ্যক্রমে এই পদ্ধতির ব্যবহার করে টেবিলের জন্য একটি আসল প্রাথমিক কী সেট করা নেই।
শান ম্যাকক্লারি

4
এই পদ্ধতিটি কমপক্ষে রেল ৪.২ এবং পোস্টগ্র্যাস্কল নিয়ে কাজ করে। আমি পরীক্ষা করেছি, তবে আপনাকে primary_key: trueকেবল primaryউত্তরে দেওয়া পরিবর্তে ব্যবহার করতে হবে
আনোয়ার

8

আমি কারাগারে 2.3.5 এ আছি এবং আমার নিম্নলিখিত পদ্ধতিতে এসকিউএলাইট 3 এর সাথে কাজ করে

create_table :widgets, { :primary_key => :widget_id } do |t|
  t.string :widget_id

  # other column definitions
end

এর প্রয়োজন নেই: আইডি => মিথ্যা।


দুঃখিত, তবে উইজেট_আইডি আমি যখন আপনার কৌশল প্রয়োগ করি তখন পূর্ণসংখ্যায় পরিবর্তিত হয়ে যাই ... আপনার কি yর্ষা সমাধান আছে?
enrique-carbonell

4
এটি আর কাজ করে না, কমপক্ষে অ্যাক্টিভেকর্ড 4.1.4 এ নয়। এটি নিম্নলিখিত ত্রুটিটি দেয়:you can't redefine the primary key column 'widgets'. To define a custom primary key, pass { id: false } to create_table.
টেমার শ্ল্যাশ

4

"এক্স ডাটাবেসে এটি আমার জন্য কাজ করে" বলে প্রায় প্রতিটি সমাধানের পরে, আমি "পোস্টগ্র্রেসে আমার পক্ষে কাজ করি না" এর প্রসঙ্গে মূল পোস্টারটির একটি মন্তব্য দেখি। এখানে আসল সমস্যাটি প্রকৃতপক্ষে রেলগুলিতে পোস্টগ্র্রেসের সমর্থন হতে পারে, যা নির্দোষ নয় এবং সম্ভবত ২০০৯ সালে এই প্রশ্নটি মূলত পোস্ট হওয়ার পরে আরও খারাপ হয়েছিল। উদাহরণস্বরূপ, যদি আমি সঠিকভাবে মনে রাখি, আপনি যদি পোস্টগ্র্রেসে থাকেন তবে আপনি মূলত এর থেকে কার্যকর আউটপুট পেতে পারবেন নাrake db:schema:dump

আমি নিজে কোনও পোস্টগ্রাস নিনজা নই, আমি পোস্টগ্রিসে জাভিয়ার শায়ের দুর্দান্ত পিপকোড ভিডিওটি থেকে এই তথ্যটি পেয়েছি। সেই ভিডিওটি আসলে অ্যারন প্যাটারসনের একটি লাইব্রেরি উপেক্ষা করেছে, আমি মনে করি টেক্সটিক্যাল তবে আমি ভুল মনে রাখতে পারি। তবে এটির চেয়েও দুর্দান্ত এটি।

যাইহোক, আপনি যদি পোস্টগ্রিসে এই সমস্যাটি চালাচ্ছেন তবে দেখুন অন্যান্য ডাটাবেসে সমাধানগুলি কাজ করে কিনা। হয়ত rails newকোনও স্যান্ডবক্স হিসাবে একটি নতুন অ্যাপ্লিকেশন তৈরি করতে ব্যবহার করুন বা এর মতো কিছু তৈরি করুন

sandbox:
  adapter: sqlite3
  database: db/sandbox.sqlite3
  pool: 5
  timeout: 5000

মধ্যে config/database.yml

এবং যদি আপনি যাচাই করতে পারেন যে এটি পোস্টগ্র্রেস সাপোর্ট ইস্যু, এবং আপনি কোনও সমাধান খুঁজে বের করতে পারেন তবে দয়া করে রেলগুলিতে প্যাচগুলি অবদান রাখুন বা আপনার ফিক্সগুলি একটি মণির মধ্যে প্যাকেজ করুন, কারণ রেল সম্প্রদায়ের মধ্যে পোস্টগ্রিসের ইউজার বেসটি বেশ বড়, প্রধানত হেরোকুকে ধন্যবাদ ।


4
এফইউডি এবং ভুলের জন্য ডাউনভোটিং। ২০০ 2007 সাল থেকে আমি আমার বেশিরভাগ রেল প্রকল্পগুলিতে পোস্টগ্রিস ব্যবহার করেছি R রিলে পোস্টগ্র্রেস সমর্থনটি দুর্দান্ত, এবং স্কিমা ডাম্পারে কোনও সমস্যা নেই।
মার্নেন লাইবো-কোসার 19

4
একদিকে, এটি সত্য যে পোস্টগ্র্রেস এখানে সমস্যা ছিল না। অন্যদিকে, এখানে ২০০৯ রেলস.লাইটহাউস অ্যাপ
গাইলস

পোস্টগ্রেস 8.3 আপডেটকে ঘিরে রেলস এবং পোস্টগ্রিসের সাথে একটি সিদ্ধান্ত নেওয়া সমস্যা ছিল যেখানে তারা (সঠিকভাবে, আইএমও) স্ট্রিং আক্ষরিক এবং উদ্ধৃতকরণের জন্য এসকিউএল স্ট্যান্ডার্ডে পরিবর্তন করার সিদ্ধান্ত নিয়েছে। রেলস অ্যাডাপ্টার পোস্টগ্রিস সংস্করণগুলি পরীক্ষা করে নি এবং কিছুক্ষণের জন্য বানরপ্যাচ করতে হয়েছিল।
জুডসন

@ জুডসন আকর্ষণীয়। আমি কখনই দৌড়ে যাইনি।
মার্নেন লাইবো-কোসার

4

আমি এর একটি সমাধান পেয়েছি যা রেল 3 এর সাথে কাজ করে:

স্থানান্তর ফাইল:

create_table :employees, {:primary_key => :emp_id} do |t|
  t.string :emp_id
  t.string :first_name
  t.string :last_name
end

এবং কর্মচারী.আরবি মডেলটিতে:

self.primary_key = :emp_id

3

রেল 3 এবং মাইএসকিউএল-এ আমার জন্য যে কৌশলটি কাজ করেছিল তা হ'ল:

create_table :events, {:id => false} do |t|
  t.string :id, :null => false
end

add_index :events, :id, :unique => true

সুতরাং:

  1. ব্যবহার করুন: আইডি => মিথ্যা যাতে কোনও পূর্ণসংখ্যার প্রাথমিক কী তৈরি করা যায় না
  2. পছন্দসই ডেটাটাইপ ব্যবহার করুন এবং যুক্ত করুন: নাল => মিথ্যা
  3. এই কলামটিতে একটি অনন্য সূচক যুক্ত করুন

দেখে মনে হচ্ছে যে মাইএসকিউএল একটি নাল কলামে অনন্য সূচকটিকে প্রাথমিক কীতে রূপান্তর করে!


মাইএসকিউএল 5.5.15 এর সাথে 3.22 জনের মধ্যে এটি একটি অনন্য কী তৈরি করে তবে প্রাথমিক কী নয়।
lulalala

2

আপনাকে বিকল্পটি ব্যবহার করতে হবে: id => মিথ্যা

create_table :employees, :id => false, :primary_key => :emp_id do |t|
    t.string :emp_id
    t.string :first_name
    t.string :last_name
end

এটি আমার পক্ষে কাজ করে না, অন্তত পোস্টগ্র্যাস এসকিউএলে নয়। কোনও প্রাথমিক কী মোটেই নির্দিষ্ট করা হয়নি।
রুড জুইলিনস্কি

4
এই পদ্ধতির আইডি কলামটি বাদ যাবে তবে প্রাথমিক কীটি আসলে টেবিলে সেট হবে না।
শান ম্যাকক্লারি

1

কিভাবে এই সমাধান সম্পর্কে,

কর্মচারী মডেলের অভ্যন্তরে আমরা কেন এমন কোড যুক্ত করতে পারি না যা কলুমনে স্বতন্ত্রতার জন্য যাচাই করবে, যেমন: উদাহরণস্বরূপ কর্মচারী এমন মডেল যা আপনার এমপিআইডের সাথে স্ট্রিং থাকে তার জন্য আমরা এমপিআইডিতে ": স্বতন্ত্রতা => সত্য" যুক্ত করতে পারি

    class Employee < ActiveRecord::Base
      validates :EmpId , :uniqueness => true
    end

আমি নিশ্চিত যে এটি সমাধান কিনা তবে এটি আমার পক্ষে কাজ করেছে।


1

আমি জানি এটি একটি পুরানো সুতো যা আমি হোঁচট খেয়েছি ... তবে আমি ধাক্কা খেয়েছি কেউ ডেটা ম্যাপার উল্লেখ করেনি।

অ্যাক্টিভেকর্ড কনভেনশন থেকে আপনার যদি বিপথগামী হওয়ার দরকার হয় তবে আমি খুঁজে পেয়েছি যে এটি একটি দুর্দান্ত বিকল্প। উত্তরাধিকারের জন্য এটির আরও ভাল পদ্ধতির এবং আপনি "যেমন রয়েছে" ডাটাবেসটিকে সমর্থন করতে পারেন।

রুবি অবজেক্ট ম্যাপার (ডেটা ম্যাপার ২) অনেক প্রতিশ্রুতি রাখে এবং এআরএল এর নীতিগুলিও তৈরি করে!


1

সূচক যুক্ত করা আমার পক্ষে কাজ করে, আমি মাইএসকিউএল বিটিডব্লু ব্যবহার করি।

create_table :cards, {:id => false} do |t|
    t.string :id, :limit => 36
    t.string :name
    t.string :details
    t.datetime :created_date
    t.datetime :modified_date
end
add_index :cards, :id, :unique => true
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.