Ruby Sequel 匹配数据错误 "can't express #<MatchData"

Ruby Sequel MatchData Error "can't express #<MatchData"

我有一个数字和文本连接在一起的变量(例如“[79511]Rocket”)。如果这个变量确实包含括号内的数字,那么我必须将(仅数字)存储在我的 table 的一列中。我正在使用以下代码对此进行验证:

enterprise_id = "[79511]Rocket".split(/[\[\]]/x)[1].match(/^(\d)+$/) rescue nil

当我使用 Puts 进行测试时,它的工作原理是 79511,很好。 但是当我 运行 代码插入数据库时​​,如下所示:

enterprise_id = "[79511]Rocket".split(/[\[\]]/x)[1].match(/^(\d)+$/) rescue nil
insert_ds = DB["INSERT INTO pd_deals ( enterprise_id ) VALUES (?)",  enterprise_id]
insert_ds.insert

目标列为table中的整数类型。

它抛出一个错误:

/home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1252:in `literal_other_append': can't express #<MatchData "79511" 1:"1"> as a SQL literal (Sequel::Error)
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:108:in `literal_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:673:in `block in placeholder_literal_string_sql_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:670:in `loop'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:670:in `placeholder_literal_string_sql_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/sql.rb:109:in `to_s_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1214:in `literal_expression_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:86:in `literal_append'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:345:in `literal'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:1534:in `static_sql'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/sql.rb:23:in `insert_sql'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/dataset/actions.rb:334:in `insert'
    from /home/bm93/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.34.0/lib/sequel/adapters/shared/postgres.rb:1355:in `insert'
    from tt.rb:12:in `<main>'

我这样做是因为我需要从字符串中提取数字。那里有什么提示吗?有没有更好的办法?

如果你执行:

"[79511]Rocket".split(/[\[\]]/x)[1].match(/^(\d)+$/)

irb 中,您将看到:

=> #<MatchData "79511" 1:"1"> 

因为 String#match returns 一个 MatchData 实例并在 MatchData 上调用 inspect 给你 #<MatchData ...>。如果您 puts 该值:

puts "[79511]Rocket".split(/[\[\]]/x)[1].match(/^(\d)+$/)

您会看到 79511,因为 puts 对其参数调用 to_s 以将它们转换为字符串。

Sequel 不会调用 to_s,它会尝试弄清楚如何将参数转换为数据库自己理解的内容,但它不知道如何处理MatchData 个实例,因此:

can't express #<MatchData "79511" 1:"1"> as a SQL literal

错误。

你可以自己打电话给to_s

DB["INSERT INTO pd_deals ( enterprise_id ) VALUES (?)",  enterprise_id.to_s.presence]

或使用MatchData#[]方法:

DB["...", enterprise_id ? enterise_id[0] : nil]

甚至如 Cary Swoveland 所建议的那样使用 String#[]

enterprise_id = "[79511]Rocket"[/(?<=\[)\d+(?=\])/]
DB["...", enterprise_id.presence]

我对 Sequel 不太熟悉,因此您可能需要一些 to_i 调用才能将 '79511' 字符串转换为 79511 数字。