<p>I've got a project that was previously using nosql and so mgo worked very well. I'm building another prototype with postgres and tried to use pq with limited success. </p>
<p>I'm not a coder by day. Just one by night. In my past, i've effectively created a db function that i can call over and over again to connect to the DB so that I don't have to rewrite that code everytime.</p>
<p>That being said, would you do this in go as well? I think the answer is yes but i'm not sure.</p>
<p>Any advice is greatly appreciated.</p>
<hr/>**评论:**<br/><br/>kpurdon: <pre><blockquote>
<p>I'm not a coder by day. Just one by night. In my past, i've effectively created a db function that i can call over and over again to connect to the DB so that I don't have to rewrite that code everytime.</p>
</blockquote>
<p>Likely you will want to create a single DB connection in the beginning of your application and pass it to whatever functions need to use the db connection. Opening a new DB connection every time you need to make a query is generally a bad idea.</p>
<p>```</p>
<pre><code>db, err := sql.Open("dbtype", "root@/somedb")
if err != nil {
log.Fatalf("%+v", errors.WithStack(err))
}
defer db.Close()
err = db.Ping()
if err != nil {
log.Fatalf("%+v", errors.WithStack(err))
}
// use it like this: (or put it in a struct that has the function as a method)
... := SomeFunctionThatNeedsADB(db, <args>)
</code></pre>
<p>```</p></pre>retinascan: <pre><p>Oh that's a good idea. </p>
<p>Do that in main.go and pass that to all the other programs.</p>
<p>Thanks!</p>
<p>I'm using PQ for it so i'll give that a try. Within this same main.go, i'm also starting up an http server so i think this might be the right place for opening a DB connection and an http server and then using handlers to call the other programs. Does that sound right?</p></pre>icholy: <pre><p>Here's the pattern I use for sharing state between routes</p>
<pre><code>type App struct {
db *sql.DB
}
func NewApp() *App {
// connect to db
}
func (app *App) LoginHandler(w http.ResponseWriter, r *http.Request) {
_ = app.db.Query(/* ... */)
}
func (app *App) HelloHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello"))
}
func main() {
app := NewApp()
http.HandleFunc("/login", app.LoginHandler)
http.HandleFunc("/hello", app.HelloHandler)
http.ListenAndServe(":8080", nil)
}
</code></pre></pre>retinascan: <pre><p>Oh that's very neat! thanks! I just learned something new there. </p></pre>retinascan: <pre><p>This may sound like yet another dumb question but I'd like to ask anyway.</p>
<p>If i start an http server (port 8080) within go and in my main.go, i start a DB connection, does that mean that for every request on port 8080, a new connection will be established to the DB? or is that the same shared connection across all the requests? I'm just concerned about simultaneous requests.</p>
<p>thanks!</p></pre>icholy: <pre><p><code>sql.DB</code> manages a pool of connections for you that grows/shrinks as need be. You can limit how many connections it's allowed to make see <a href="https://godoc.org/database/sql#DB.SetMaxOpenConns" rel="nofollow">func (*DB) SetMaxOpenConns</a>. It's also thread safe so it's perfectly fine to use it from multiple goroutines at the same time.</p></pre>kpurdon: <pre><p><a href="/u/icholy" rel="nofollow">/u/icholy</a> already commented with basically the pattern I use for everything. Here is a demo app I've been working on that you can poke around in to see it working full-cycle. <a href="https://github.com/kpurdon/beercellar" rel="nofollow">https://github.com/kpurdon/beercellar</a></p></pre>retinascan: <pre><p>Oh wow! thanks!</p></pre>alioygur: <pre><p>Sorry, is the errors.WithStack custom package?</p></pre>kpurdon: <pre><p>Yes. <a href="https://github.com/pkg/errors" rel="nofollow">https://github.com/pkg/errors</a>. It's a package that will likely be proposed as a future addition to the stdlib. It provides some really awesome additions/patterns to stdlib errors.</p></pre>aarondl: <pre><p>Keep in mind that the sql package is quite verbose and you're likely going to want to use a package that helps you with doing queries against the database. I'd say you should use <a href="https://github.com/vattle/sqlboiler" rel="nofollow">https://github.com/vattle/sqlboiler</a> (disclaimer: I'm one of the authors). If you don't like that one I think you should give at least sqlx a try.</p></pre>retinascan: <pre><p>Hi. Thanks. I will take a look at your project. I was trying to use pq at the moment. My database is very simple at the moment and I'm just trying to prototype some stuff. So i'll likely stick with this until i'm more proficient with go.</p></pre>kpurdon: <pre><p>For a "very simple" db you should totally just start out with <code>database/sql</code> (and whatever driver) and only add something like an ORM when you need to. I've got large production services with lot's of tables using nothing but <code>database/sql</code> very happily.</p></pre>kpurdon: <pre><p>I'm not sure I agree that the sql package is "quite verbose". For small-medium projects that don't have a ton of relationships, it's very suitable. For anything with more than a few tables and relationships, I will concede that one should consider an ORM of some form.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传