如何使用PG gem向Postgres表中插入数据

3

我使用Postgres创建了三个数据库模式。表肯定存在,我使用shell和\dt命令来查看它们。

当我尝试使用seeds.rb文件进行INSERT时,My SqlRunner失败了。终端返回PG :: SyntaxError:在“11.18”附近或之前。前一行也是浮点数,所以我不知道哪里出错了。

模型如下:

require('pg')
require('../project_giclee_db/sql_runner')


class Material

  attr_reader :id, :product_name, :guk_name, :roll_width_in,  :roll_length_metres, :list_price, :cost_per_sqm,
    :cost_per_sqm_with_ink, :factor_n, :sell_per_sqm, :rounded_sale_price


  def initialize( options )
    @id = options['id'].to_i
    @product_name = options['product_name']
    @guk_name = options['guk_name']
    @roll_width_in = options['roll_width_in'].to_i
    @roll_length_metres = options['roll_length_metres'].to_i
    @list_price = options['list_price'].to_f
    @cost_per_sqm = options['cost_per_sqm'].to_f
    @cost_per_sqm_with_ink = options['cost_per_sqm_with_ink'].to_f
    @factor_n = options['factor_n'].to_f
    @sell_per_sqm = options['sell_per_sqm'].to_f
    @rounded_sale_price = options['rounded_sale_price'].to_i

  end


  def save
    sql = "INSERT INTO materials (product_name, guk_name, roll_width_in, roll_length_metres,
    list_price, cost_per_sqm, cost_per_sqm_with_ink, factor_n, sell_per_sqm, rounded_sale_price)
    VALUES (#{@product_name}, #{@guk_name}, #{@roll_width_in}, #{@roll_length_metres}, #{@list_price}
    #{@cost_per_sqm}, #{@cost_per_sqm_with_ink}, #{@factor_n}, #{@sell_per_sqm}, #{@rounded_sale_price}
    ) RETURNING *"

    data = SqlRunner.run(sql).first
    @id = data['id']
  end


  def self.delete_all
    sql = "DELETE FROM materials"
    SqlRunner.run(sql)
  end

end

Runner的外观如下:

require('pg')

class SqlRunner

  def self.run(sql)
    begin
   db = PG.connect( {dbname: 'giclee_db', host: 'localhost'} )
     result = db.exec(sql)
    ensure
    db.close
  end
   return result
 end

end

种子数据的样式如下:
require('../models/materials')
require('pry-byebug')

Material.delete_all

 @material1 = Material.new( { 'product_name' => 'giclee_canvas',   'guk_name' => 'canvas',
'roll_width_in' => 44, 'roll_length_metres' => 12, 'list_price' => 150.00,
'cost_per_sqm' => 11.18, 'cost_per_sqm_with_ink' => 14.18, 'factor_n' => 11.00,
'sell_per_sqm' => 156.03, 'rounded_sale_price' => 156
} )


@material1.save

如果你没有使用Rails,我强烈推荐使用Sequel来连接数据库。它是一个非常好的ORM,可以让你更轻松地生成查询或语句,无需担心语法问题。Pg 强制你编写特定于 PostgreSQL 的 SQL 语句。而 Sequel 允许你使用 Ruby 来生成 SQL,并且与DBM无关,支持许多不同的DBMs,你只需要更改 DSN 就能自动生成适用于不同数据库类型的等效查询。 - the Tin Man
在 Ruby 中,习惯上不在 require 参数周围使用括号。另外,@material1 暴露出您对 Ruby 变量及其作用域的理解不够,我建议您熟悉类、实例和局部变量以及常量。 - the Tin Man
我承认我在这方面相对新手,但你提到的任何事情都不会影响SqlRunner。 - godhar
你所说的是风格问题,我学习时被教导在那里加上括号,所以我出于习惯这样做。 - godhar
Pg作为与PostgreSQL交流的驱动程序非常出色,但是当有好的ORM可用时,手写SQL并不是一个好的时间利用方式。Sequel得到了很好的维护,并且作者使用Postgres作为他的数据库,因此Sequel对其提供了很好的支持。 - the Tin Man
显示剩余4条评论
2个回答

1

你应该在字符串周围加上引号:

def save
 sql = "INSERT INTO materials (product_name, guk_name, roll_width_in, roll_length_metres,
list_price, cost_per_sqm, cost_per_sqm_with_ink, factor_n, sell_per_sqm, rounded_sale_price)
VALUES ('#{@product_name}', '#{@guk_name}', #{@roll_width_in}, #{@roll_length_metres}, #{@list_price}
#{@cost_per_sqm}, #{@cost_per_sqm_with_ink}, #{@factor_n}, #{@sell_per_sqm}, #{@rounded_sale_price}
) RETURNING *"

  data = SqlRunner.run(sql).first
  @id = data['id']
end

好的喊声 @eiko,但是我收到了相同的错误。已经做出了更改,进步就是进步。 - godhar

0
问题在于SQL语句末尾缺少逗号:
VALUES ('#{@product_name}', '#{@guk_name}', #{@roll_width_in}, #{@roll_length_metres}, #{@list_price}

变量sql中的换行符也不好。尝试去掉换行符。sql = "INSERT INTO materials (product_name, guk_name, roll_width_in, roll_length_metres, list_price, cost_per_sqm, cost_per_sqm_with_ink, factor_n, sell_per_sqm, rounded_sale_price) VALUES ('#{@product_name}', '#{@guk_name}', #{@roll_width_in}, #{@roll_length_metres}, #{@list_price}, #{@cost_per_sqm}, #{@cost_per_sqm_with_ink}, #{@factor_n}, #{@sell_per_sqm}, #{@rounded_sale_price} ) RETURNING *" - rafael.cote
无论如何,我现在处于紧急情况下,但是我已经打开了 pry 装置并拥有一个返回的对象哈希。谢谢。 - godhar
@godhar 我以为执行时 "\n" 会报错,但对我来说它是有效的。 - rafael.cote
请更具体一些。逗号缺失在哪里?SQL中嵌入行断点是可以的。有机会在命令行中尝试一下。 - the Tin Man
@theTinMan 添加有问题的代码行。我在stackoverflow上开始了解决方案。 - rafael.cote
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接