连接 Ruby 和 MySQL

Connect Ruby and MySQL

正在尝试连接 ruby 和 mysql。当运行访问数据库的基本脚本出现错误时:

Unable to load driver 'Mysql' (underlying error: uninitialized constant DBI::DBD::Mysql) (DBI::InterfaceError)

谷歌搜索并找到解决方案:

第一个,给出错误:

checking for mysql_ssl_set()... yes
checking for rb_str_set_len()... yes
checking for rb_thread_start_timer()... no
checking for mysql.h... yes
creating Makefile

current directory: /home/wheatman/.rvm/gems/ruby-2.7.2/gems/mysql-2.9.1/ext/mysql_api
make "DESTDIR=" clean

current directory: /home/wheatman/.rvm/gems/ruby-2.7.2/gems/mysql-2.9.1/ext/mysql_api
make "DESTDIR="
compiling mysql.c
mysql.c:79:2: error: unknown type name ‘my_bool’
   79 |  my_bool *is_null;
      |  ^~~~~~~
mysql.c: In function ‘options’:
mysql.c:361:5: error: unknown type name ‘my_bool’; did you mean ‘bool’?
  361 |     my_bool b;
      |     ^~~~~~~
      |     bool
mysql.c:391:10: error: ‘MYSQL_SET_CLIENT_IP’ undeclared (first use in this function); did you mean ‘MYSQL_SET_CHARSET_DIR’?
  391 |     case MYSQL_SET_CLIENT_IP:
      |          ^~~~~~~~~~~~~~~~~~~
      |          MYSQL_SET_CHARSET_DIR
mysql.c:391:10: note: each undeclared identifier is reported only once for each function it appears in
mysql.c:398:10: error: ‘MYSQL_SECURE_AUTH’ undeclared (first use in this function); did you mean ‘MYSQL_DEFAULT_AUTH’?
  398 |     case MYSQL_SECURE_AUTH:
      |          ^~~~~~~~~~~~~~~~~
      |          MYSQL_DEFAULT_AUTH
mysql.c: In function ‘stmt_init’:
mysql.c:878:5: error: ‘my_bool’ undeclared (first use in this function)
  878 |     my_bool true = 1;
      |     ^~~~~~~
mysql.c:878:12: error: expected ‘;’ before numeric constant
  878 |     my_bool true = 1;
      |            ^
      |            ;
mysql.c:883:61: error: lvalue required as unary ‘&’ operand
  883 |     if (mysql_stmt_attr_set(s, STMT_ATTR_UPDATE_MAX_LENGTH, &true))
      |                                                             ^
mysql.c: In function ‘stmt_bind_result’:
mysql.c:1320:74: error: ‘rb_cFixnum’ undeclared (first use in this function)
 1320 |  else if (argv[i] == rb_cNumeric || argv[i] == rb_cInteger || argv[i] == rb_cFixnum)
      |                                                                          ^~~~~~~~~~
mysql.c: In function ‘stmt_prepare’:
mysql.c:1681:32: warning: assignment to ‘_Bool *’ from incompatible pointer type ‘int *’ [-Wincompatible-pointer-types]
 1681 |      s->result.bind[i].is_null = &(s->result.is_null[i]);
      |                                ^
In file included from /home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby.h:33,
                 from mysql.c:5:
mysql.c: In function ‘Init_mysql_api’:
mysql.c:2049:52: error: ‘MYSQL_SECURE_AUTH’ undeclared (first use in this function); did you mean ‘MYSQL_DEFAULT_AUTH’?
 2049 |     rb_define_const(cMysql, "SECURE_AUTH", INT2NUM(MYSQL_SECURE_AUTH));
      |                                                    ^~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2049:44: note: in expansion of macro ‘INT2NUM’
 2049 |     rb_define_const(cMysql, "SECURE_AUTH", INT2NUM(MYSQL_SECURE_AUTH));
      |                                            ^~~~~~~
mysql.c:2050:61: error: ‘MYSQL_OPT_GUESS_CONNECTION’ undeclared (first use in this function); did you mean ‘MYSQL_OPT_RECONNECT’?
 2050 |     rb_define_const(cMysql, "OPT_GUESS_CONNECTION", INT2NUM(MYSQL_OPT_GUESS_CONNECTION));
      |                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2050:53: note: in expansion of macro ‘INT2NUM’
 2050 |     rb_define_const(cMysql, "OPT_GUESS_CONNECTION", INT2NUM(MYSQL_OPT_GUESS_CONNECTION));
      |                                                     ^~~~~~~
mysql.c:2051:68: error: ‘MYSQL_OPT_USE_EMBEDDED_CONNECTION’ undeclared (first use in this function)
 2051 |     rb_define_const(cMysql, "OPT_USE_EMBEDDED_CONNECTION", INT2NUM(MYSQL_OPT_USE_EMBEDDED_CONNECTION));
      |                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2051:60: note: in expansion of macro ‘INT2NUM’
 2051 |     rb_define_const(cMysql, "OPT_USE_EMBEDDED_CONNECTION", INT2NUM(MYSQL_OPT_USE_EMBEDDED_CONNECTION));
      |                                                            ^~~~~~~
mysql.c:2052:66: error: ‘MYSQL_OPT_USE_REMOTE_CONNECTION’ undeclared (first use in this function)
 2052 |     rb_define_const(cMysql, "OPT_USE_REMOTE_CONNECTION", INT2NUM(MYSQL_OPT_USE_REMOTE_CONNECTION));
      |                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2052:58: note: in expansion of macro ‘INT2NUM’
 2052 |     rb_define_const(cMysql, "OPT_USE_REMOTE_CONNECTION", INT2NUM(MYSQL_OPT_USE_REMOTE_CONNECTION));
      |                                                          ^~~~~~~
mysql.c:2053:54: error: ‘MYSQL_SET_CLIENT_IP’ undeclared (first use in this function); did you mean ‘MYSQL_SET_CHARSET_DIR’?
 2053 |     rb_define_const(cMysql, "SET_CLIENT_IP", INT2NUM(MYSQL_SET_CLIENT_IP));
      |                                                      ^~~~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2053:46: note: in expansion of macro ‘INT2NUM’
 2053 |     rb_define_const(cMysql, "SET_CLIENT_IP", INT2NUM(MYSQL_SET_CLIENT_IP));
      |                                              ^~~~~~~
error_const.h:2661:27: error: ‘ER_XPLUGIN_IP’ undeclared (first use in this function); did you mean ‘ER_PLUGIN_OOM’?
 2661 |     rb_define_mysql_const(ER_XPLUGIN_IP);
      |                           ^~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2286:62: note: in expansion of macro ‘INT2NUM’
 2286 | #define rb_define_mysql_const(s) rb_define_const(eMysql, #s, INT2NUM(s))
      |                                                              ^~~~~~~
error_const.h:2661:5: note: in expansion of macro ‘rb_define_mysql_const’
 2661 |     rb_define_mysql_const(ER_XPLUGIN_IP);
      |     ^~~~~~~~~~~~~~~~~~~~~
mysql.c: At top level:
cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics
make: *** [Makefile:245: mysql.o] Error 1

make failed, exit code 2

Gem files will remain installed in /home/wheatman/.rvm/gems/ruby-2.7.2/gems/mysql-2.9.1 for inspection.
Results logged to /home/wheatman/.rvm/gems/ruby-2.7.2/extensions/x86_64-linux/2.7.0/mysql-2.9.1/gem_make.out

而第二个给出另一个错误:

Building native extensions. This could take a while...
ERROR:  Error installing dbd-mysql:
    ERROR: Failed to build gem native extension.

    current directory: /home/wheatman/.rvm/gems/ruby-2.7.2/gems/mysql-2.9.1/ext/mysql_api
/home/wheatman/.rvm/rubies/ruby-2.7.2/bin/ruby -I /home/wheatman/.rvm/rubies/ruby-2.7.2/lib/ruby/2.7.0 -r ./siteconf20201219-250830-klyeov.rb extconf.rb
checking for mysql_ssl_set()... yes
checking for rb_str_set_len()... yes
checking for rb_thread_start_timer()... no
checking for mysql.h... yes
creating Makefile

current directory: /home/wheatman/.rvm/gems/ruby-2.7.2/gems/mysql-2.9.1/ext/mysql_api
make "DESTDIR=" clean

current directory: /home/wheatman/.rvm/gems/ruby-2.7.2/gems/mysql-2.9.1/ext/mysql_api
make "DESTDIR="
compiling mysql.c
mysql.c:79:2: error: unknown type name ‘my_bool’
   79 |  my_bool *is_null;
      |  ^~~~~~~
mysql.c: In function ‘options’:
mysql.c:361:5: error: unknown type name ‘my_bool’; did you mean ‘bool’?
  361 |     my_bool b;
      |     ^~~~~~~
      |     bool
mysql.c:391:10: error: ‘MYSQL_SET_CLIENT_IP’ undeclared (first use in this function); did you mean ‘MYSQL_SET_CHARSET_DIR’?
  391 |     case MYSQL_SET_CLIENT_IP:
      |          ^~~~~~~~~~~~~~~~~~~
      |          MYSQL_SET_CHARSET_DIR
mysql.c:391:10: note: each undeclared identifier is reported only once for each function it appears in
mysql.c:398:10: error: ‘MYSQL_SECURE_AUTH’ undeclared (first use in this function); did you mean ‘MYSQL_DEFAULT_AUTH’?
  398 |     case MYSQL_SECURE_AUTH:
      |          ^~~~~~~~~~~~~~~~~
      |          MYSQL_DEFAULT_AUTH
mysql.c: In function ‘stmt_init’:
mysql.c:878:5: error: ‘my_bool’ undeclared (first use in this function)
  878 |     my_bool true = 1;
      |     ^~~~~~~
mysql.c:878:12: error: expected ‘;’ before numeric constant
  878 |     my_bool true = 1;
      |            ^
      |            ;
mysql.c:883:61: error: lvalue required as unary ‘&’ operand
  883 |     if (mysql_stmt_attr_set(s, STMT_ATTR_UPDATE_MAX_LENGTH, &true))
      |                                                             ^
mysql.c: In function ‘stmt_bind_result’:
mysql.c:1320:74: error: ‘rb_cFixnum’ undeclared (first use in this function)
 1320 |  else if (argv[i] == rb_cNumeric || argv[i] == rb_cInteger || argv[i] == rb_cFixnum)
      |                                                                          ^~~~~~~~~~
mysql.c: In function ‘stmt_prepare’:
mysql.c:1681:32: warning: assignment to ‘_Bool *’ from incompatible pointer type ‘int *’ [-Wincompatible-pointer-types]
 1681 |      s->result.bind[i].is_null = &(s->result.is_null[i]);
      |                                ^
In file included from /home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby.h:33,
                 from mysql.c:5:
mysql.c: In function ‘Init_mysql_api’:
mysql.c:2049:52: error: ‘MYSQL_SECURE_AUTH’ undeclared (first use in this function); did you mean ‘MYSQL_DEFAULT_AUTH’?
 2049 |     rb_define_const(cMysql, "SECURE_AUTH", INT2NUM(MYSQL_SECURE_AUTH));
      |                                                    ^~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2049:44: note: in expansion of macro ‘INT2NUM’
 2049 |     rb_define_const(cMysql, "SECURE_AUTH", INT2NUM(MYSQL_SECURE_AUTH));
      |                                            ^~~~~~~
mysql.c:2050:61: error: ‘MYSQL_OPT_GUESS_CONNECTION’ undeclared (first use in this function); did you mean ‘MYSQL_OPT_RECONNECT’?
 2050 |     rb_define_const(cMysql, "OPT_GUESS_CONNECTION", INT2NUM(MYSQL_OPT_GUESS_CONNECTION));
      |                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2050:53: note: in expansion of macro ‘INT2NUM’
 2050 |     rb_define_const(cMysql, "OPT_GUESS_CONNECTION", INT2NUM(MYSQL_OPT_GUESS_CONNECTION));
      |                                                     ^~~~~~~
mysql.c:2051:68: error: ‘MYSQL_OPT_USE_EMBEDDED_CONNECTION’ undeclared (first use in this function)
 2051 |     rb_define_const(cMysql, "OPT_USE_EMBEDDED_CONNECTION", INT2NUM(MYSQL_OPT_USE_EMBEDDED_CONNECTION));
      |                                                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2051:60: note: in expansion of macro ‘INT2NUM’
 2051 |     rb_define_const(cMysql, "OPT_USE_EMBEDDED_CONNECTION", INT2NUM(MYSQL_OPT_USE_EMBEDDED_CONNECTION));
      |                                                            ^~~~~~~
mysql.c:2052:66: error: ‘MYSQL_OPT_USE_REMOTE_CONNECTION’ undeclared (first use in this function)
 2052 |     rb_define_const(cMysql, "OPT_USE_REMOTE_CONNECTION", INT2NUM(MYSQL_OPT_USE_REMOTE_CONNECTION));
      |                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2052:58: note: in expansion of macro ‘INT2NUM’
 2052 |     rb_define_const(cMysql, "OPT_USE_REMOTE_CONNECTION", INT2NUM(MYSQL_OPT_USE_REMOTE_CONNECTION));
      |                                                          ^~~~~~~
mysql.c:2053:54: error: ‘MYSQL_SET_CLIENT_IP’ undeclared (first use in this function); did you mean ‘MYSQL_SET_CHARSET_DIR’?
 2053 |     rb_define_const(cMysql, "SET_CLIENT_IP", INT2NUM(MYSQL_SET_CLIENT_IP));
      |                                                      ^~~~~~~~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2053:46: note: in expansion of macro ‘INT2NUM’
 2053 |     rb_define_const(cMysql, "SET_CLIENT_IP", INT2NUM(MYSQL_SET_CLIENT_IP));
      |                                              ^~~~~~~
error_const.h:2661:27: error: ‘ER_XPLUGIN_IP’ undeclared (first use in this function); did you mean ‘ER_PLUGIN_OOM’?
 2661 |     rb_define_mysql_const(ER_XPLUGIN_IP);
      |                           ^~~~~~~~~~~~~
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:262:33: note: in definition of macro ‘RB_INT2FIX’
  262 | #define RB_INT2FIX(i) (((VALUE)(i))<<1 | RUBY_FIXNUM_FLAG)
      |                                 ^
/home/wheatman/.rvm/rubies/ruby-2.7.2/include/ruby-2.7.0/ruby/ruby.h:1609:20: note: in expansion of macro ‘RB_INT2NUM’
 1609 | #define INT2NUM(x) RB_INT2NUM(x)
      |                    ^~~~~~~~~~
mysql.c:2286:62: note: in expansion of macro ‘INT2NUM’
 2286 | #define rb_define_mysql_const(s) rb_define_const(eMysql, #s, INT2NUM(s))
      |                                                              ^~~~~~~
error_const.h:2661:5: note: in expansion of macro ‘rb_define_mysql_const’
 2661 |     rb_define_mysql_const(ER_XPLUGIN_IP);
      |     ^~~~~~~~~~~~~~~~~~~~~
mysql.c: At top level:
cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics
cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics
make: *** [Makefile:245: mysql.o] Error 1

make failed, exit code 2

Gem files will remain installed in /home/wheatman/.rvm/gems/ruby-2.7.2/gems/mysql-2.9.1 for inspection.
Results logged to /home/wheatman/.rvm/gems/ruby-2.7.2/extensions/x86_64-linux/2.7.0/mysql-2.9.1/gem_make.out

我正在使用 Ubuntu 20.10、ruby 2.7.2 和 mysql 8.0.22,据我了解版本中的问题。有人遇到过这样的问题吗?是版本问题吗?是否有机会将 ruby 和 mysql 与我的版本连接起来,或者我需要回到旧版本?

您使用的是非常过时和废弃的工具。 mysql gem 自 2013 年以来就没有发布过新版本,而 dbd-mysql 自 2010 年以来就没有更新过。它们能否与现代版本的 Ruby 和 MySQL.

您想要的是积极维护的 mysql2 gem

# https://bundler.io/guides/bundler_in_a_single_file_ruby_script.html
require 'bundler/inline'
gemfile do
  source 'https://rubygems.org'
  gem 'mysql2', '~> 0.5.2'
end

client = Mysql2::Client.new(host: "localhost", username: "root")
results = client.query("SELECT * FROM users")
results.each do |row|
  # do something with row, it's ready to rock
end