英文:
how can I compile a Go database/sql program with multiple drivers?
问题
我正在为sql数据库(Postgres和Mysql)编写一个Go的测试程序。目前,我对于包中的"_"选项并不了解,但我正在使用它(见下文)。
我希望能够编译一次,然后在一个关系型数据库管理系统(RDBMS)中使用多个sql驱动程序,也可以在多个RDBMS中使用多个驱动程序,并在运行程序时选择要使用的驱动程序和RDBMS。我不确定是否可能实现这一点。目前,我使用一个Postgres驱动程序和一个Mysql驱动程序进行编译,然后在运行时选择使用哪个(Postgres/Mysql)。这样做可以正常工作,但我需要记住编译时使用的驱动程序。能够编译多个驱动程序用于一个RDBMS,然后在运行时选择使用哪个驱动程序会很好。我猜这是不可能的。或者,能够在编译时选择要使用的驱动程序,并在运行时知道正在使用哪些驱动程序,也是一个不错的选择。如果没有这些功能之一,一个人可能会测试例如Postgres,并认为他们正在使用一个驱动程序,而实际上程序已经被编译为使用另一个驱动程序。
是否可能有一个编译器选项来选择特定的驱动程序,然后在运行时知道正在使用哪个驱动程序?另一种选择显然是编辑程序来指示这一点。
导入的一个示例如下:
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
////_ "github.com/lib/pq"
_ "github.com/lxn/go-pgsql"
........
英文:
I'm writing a test program in Go for sql databases (Postgres and Mysql) currently. I don't know much about the "_" option for packages however I am using it (see below).
What I would like to be able to do is to compile once to use multiple sql drivers for the one RDBMS and also for multiple RDBMS's and when running the program, select which driver and RDBMS to use. I'm not sure if that's possible. Currently I compile with one Postgres and one Mysql driver and then select which one I'm using at run time (Postgres/Mysql). That works OK, but I need to remember which driver was compiled. It would be good to be able to compile with multiple drivers for the one RDBMS and then at run-time select which one to use. I guess that's not possible. Alternatively it would be good to be able to select at compile time which drivers to use, and at run-time to know which drivers are being used. Without one of these facilities, one could be testing eg. Postgres and think they are using one driver when in fact the program has been compiled with another driver.
Is it possible to have a compiler option to select particular drivers, and then at run-time know which driver is being used? An alternative is obviously to edit the program to indicate this.
An example of the import is as follows :
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
////_ "github.com/lib/pq"
_ "github.com/lxn/go-pgsql"
........
答案1
得分: 8
我不太了解关于包中的“_”选项,但是我正在使用它(见下文)。
在导入路径前加上“_”将正常导入该包(运行其“init()”函数),但不会将导入的包与当前包中的名称关联起来。
我想要实现的是只编译一次,然后在一个关系型数据库管理系统(RDBMS)中使用多个SQL驱动程序,也可以在多个RDBMS中使用多个SQL驱动程序。在运行程序时,可以选择要使用的驱动程序和RDBMS。我不确定是否可能实现这一点。
包“github.com/go-sql-driver/mysql”的“init()”函数执行以下操作:
func init() {
sql.Register("mysql", &MySQLDriver{})
}
它将调用database/sql
的Register
函数,该函数定义如下:
func Register(name string, driver driver.Driver)
并具有以下条件:
如果使用相同的名称两次调用Register函数,或者driver为nil,则会引发panic。
在注册了驱动程序之后,可以使用sql.Open
打开到数据库的新连接,使用第一个参数指定的驱动程序,例如:
db, e := sql.Open("mysql", "user:pass@host:port")
顺便说一下,github.com/lxn/go-pgsql
的init()
函数如下所示:
func init() {
sql.Register("postgres", sqlDriver{})
}
我重新阅读了你的问题,我认为你还想在运行程序时指定要使用的数据库和驱动程序。
为此,你可以使用flag
包,像这样运行你的应用程序:
./my_app -driver=mysql -db="user:pass@host:port"
然后将这些字符串传递给sql.Open
函数。
英文:
> I don't know much about the "_" option for packages however I am using it (see below).
Prepending _
to a import path will import the package just normally (running its' init()
function) but it won't associate a name in your current package with the imported package.
> What I would like to be able to do is to compile once to use multiple sql drivers for the one RDBMS and also for multiple RDBMS's and when running the program, select which driver and RDBMS to use. I'm not sure if that's possible.
The init()
function of package "github.com/go-sql-driver/mysql"
does the following:
func init() {
sql.Register("mysql", &MySQLDriver{})
}
It will call database/sql
's Register
function which is defined to be:
func Register(name string, driver driver.Driver)
And has the condition:
> If Register is called twice with the same name or if driver is nil, it panics.
After a driver has been registered, you can use sql.Open
:
func Open(driverName, dataSourceName string) (*DB, error)
to open a new connection to a database, using the driver specified by the first argument, e.g:
db, e := sql.Open("mysql", "user:pass@host:port")
By the way, github.com/lxn/go-pgsql
's init()
function looks like this:
func init() {
sql.Register("postgres", sqlDriver{})
}
<hr>
I have re-read your question and I think that additionally, you'd like to specify what database and driver you want to use when running the program.
For this, you can use the flag
package and run your application like this:
./my_app -driver=mysql -db="user:pass@host:port"
and pass these strings to sql.Open
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论