2012-04-27 2 views
3

나는 다음 루비 코드를 한 :어떻게 데이터베이스 테이블에 배열을 삽입합니까?

94 def open_connection(info) 
95  self.log "opening #{info.inspect}" 
96  db = Mysql.init 
97  db.options(Mysql::SET_CHARSET_NAME, 'utf8') 
98  db.real_connect(info.host, info.user, info.password, info.dbname, info.port) 
99  db.query("SET NAMES utf8") 
100 »···res = db.query("SELECT realname FROM profiles") 
101 
102 »···conn = PGconn.connect("localhost", 5432, '', '', "dbname", "user", "pwd") 

어떻게 걸릴 않는 res 내 포스트 그레스 데이터베이스에 삽입을 통해 변수 및 루프?

+0

나는 매우를 제외하고, DB 작업의 가장 사소한를 ORM을 사용하는 것이 좋습니다 것 . 나는 [Sequel] (http://sequel.rubyforge.org/)을 좋아하지만 [Datamapper] (http://datamapper.org/)와 [ActiveRecord] (http://ar.rubyonrails.org/)는 좋다. 또한. 좋은 ORM으로 큰 승리를 거둔 것은 다른 DBM으로 전환해야 할 때 코드가 변경되지 않는다는 것입니다. –

+0

@theTinMan : ORM의 단점은 일회성을 위해 많은 노력이 필요하다는 것과 동시에 두 개의 다른 데이터베이스와 대화하게하는 것이 어려울 수 있다는 것입니다. 또한 ORM은 데이터베이스 고유의 데이터 유형 (예 : PostgreSQL의 풍부하지만 비표준 유형)과 고급 SQL 기능 (예 : 트리거 및 창 기능)에 문제가있는 경향이 있습니다. 나는 Ruby ORM 경험의 대부분이 (불행히도) ActiveRecord를 사용하고 있고, 다른 것들은 더 나은 태도를 가지며 제한이 적을 수 있음을 지적함으로써이를 증명할 것입니다. –

+1

FWIW, [Sequel] (http://sequel.rubyforge.org/index.html)은 여러 데이터베이스와 대화하기가 어렵지 않고 일반적으로 원시 SQL 문과 동일한 작업에 대한 입력이 적습니다. 윈 - 윈 (그리고 아니요, 단지 데이터 세트를 사용하여 실제 ORM이 아니기 때문에 효율적이고 사용하기 쉽습니다). – Phrogz

답변

3

당신이 배열로 각 행을 얻을 each을 사용할 수 있도록 MySQL의 query 방법은 당신에게 Mysql::Result 인스턴스를 제공합니다

당신이 결과에 더 열을 작업하기 쉬울 수 있습니다 다음 each_hash을 설정 한 경우
res = db.query('select realname from profiles') 
res.each do |a| 
    # a is an array of strings 
    realname = a.first 
    # ... 
end 

, 그 열 이름을 자신의 값에 매핑 해시로 블록을 호출합니다.

의 PostgreSQL에 데이터를 삽입하려면 exec 사용

pg_conn.exec('insert into some_table (some_column) values ($1)', [ realname ]) 

당신은 또한 prepareexec_prepared를 사용할 수있는 1999

에서 PHP 프로그래머처럼 파티를 할 필요가 없습니다, 오히려 보간보다 자리를 사용하십시오 :

pg_conn.prepare('ins', 'insert into some_table (some_column) values ($1)') 
pg_conn.exec_prepared('ins', [ realname1 ]) 
pg_conn.exec_prepared('ins', [ realname2 ]) 
# ... 

prepare o 같은 SQL을 계속해서 반복적으로 실행해야한다. 당신이 import 사용할 수 있습니다 중 하나 Sequel DB 라이브러리를 사용

res = db.query('select realname from profiles') 
pg_conn.prepare('ins', 'insert into some_table (some_column) values ($1)') 
res.each { |a| pg_conn.exec_prepared('ins', a) } 
+0

이렇게 : res = db.query ('프로필에서 실제 이름 선택') res.each do | a | realname = a.first end pg_conn.prepare ('ins', some_table (some_column) 값 ($ 1)에 삽입) res.each {| a | pg_conn.exec_prepared ('ins', a)} 이 정보가 맞습니까? – wonbyte

+0

@wonbyte : 당신은'res.each do | a | # a is an ... ', 그냥'res = db.query (...); pg_conn.prepare ('ins', ...); res.each {| a | ...}'. –

+0

맨 끝에 코드의 첫 번째 줄을, 맨 아래에 마지막 두 줄을 입력하십시오. Ruby에 새 소식 – wonbyte

2

: 그들을 결합

는 일을 얻을 수

# When `res` is an array of just values 
res = MYSQLDB[:profiles].select_map(:realname) 
PGDB[:profiles].import([:realname],res) 

중 & hellip, 또는 당신이 사용할 수있는 multi_insert :

# When `res` is an array of hashes mapping column name to value 
res = MYSQLDB[:profiles].select(:realname).all 
PGDB[:profiles].multi_insert(res) 

위의 중 하나를 사용하여 optiona 할 수 있습니다. 에서야 (메모리를 적게 사용하고 결과적으로 더 성능이 좋은 경우도있다) 일괄 삽입 할 수있는 옵션이 마지막 매개 변수를 전달 :

PGDB[:profiles].import([:realname],res,commit_every:500) 
PGDB[:profiles].multi_insert(res,commit_every:500) 
+0

+1. 왜 내가 후편을 사용하는지, 그리고 왜 그렇게 좋은지에 대한 훌륭한 예입니다. –

관련 문제