<p>I hate ORMs, but I also hate taking a crapload of time to get my application off the ground because I'm stuck writing braindead SQL statements. What I want is something that'll read a database schema and generate up a bunch of Go functions with the proper SQL statements prefilled for all the usual operations, i.e. </p>
<pre><code>// generated code, do not modify!!
// OrdersByUserID returns the Orders that belong to the given user.
func OrdersByUserID(userid string) ([]Order, error) {
// or something, this is just an example, don't bikeshed, kthxbye.
rows, err := db.Query("SELECT * FROM orders WHERE user_id=?", userid)
// populate slice & structs
return orders, nil
}
</code></pre>
<p>Obviously, such a generator can't generate everything you'd ever want, but the simple CRUD stuff seems eminently doable... </p>
<p>Has anyone written something like this? All I see are fluent-ish Go APIs for generating SQL, which to me seems like the worst of both worlds (if I didn't want to write SQL, why would I want to write Go code that looks like SQL?)</p>
<hr/>**评论:**<br/><br/>tlianza: <pre><p>I don't know of a solution that exists, but I really like the idea. </p></pre>inanotherworld: <pre><p>Rather than generate it from the database schema, why not generate if from struct tags and also generate the db schema from the struct tags too?</p>
<p>Anyhow, not sure if it exists yet, but would be useful.</p></pre>natefinch: <pre><p>Well, so those are two opposite ends of the spectrum - code first and database first. I think that since code is a lot more flexible than a database, it's probably a lot easier to start database first... plus then there's absolutely no ambiguity about how to define the code. In fact, you don't even need struct tags, because all the code is generated for you and guaranteed to match the DB.</p></pre>schumacherfm: <pre><p>I must use the DB first approach because the DB Schema of ~300 tables is given by another system. Struct, Slice + general method receivers on each struct or slice type are all generated. Some functions are still missing. For special queries (for an very advanced <a href="https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model" rel="nofollow">EAV model</a>) I have a SQL query to struct generator.</p></pre>inanotherworld: <pre><p>Replying to my own comment - I forgot about this package -
<a href="https://github.com/drone/sqlgen" rel="nofollow">https://github.com/drone/sqlgen</a></p>
<p>It looks promising.</p></pre>j1436go: <pre><p>Wrote something limited to Postgres and simple CRUD operations. Worked pretty well for simple CRUD actually...
It's not very flexible and somewhat adapted to my personal style so I don't think it's quite ready for release.
If there's interest in it, I can share the source though so someone else can work out a more generic solution on top of that.</p></pre>natefinch: <pre><p>I'd certainly love to see it, even with caveats about it being not a general purpose solution.</p></pre>robertmeta: <pre><p><a href="https://git.is-a-dev.com/is-a-dev.com/autoapi" rel="nofollow">https://git.is-a-dev.com/is-a-dev.com/autoapi</a> -- I looked at this a bit ago, it generates statements + REST frontend but might be useful. </p>
<p>There is also <a href="https://github.com/manishrjain/gocrud" rel="nofollow">https://github.com/manishrjain/gocrud</a> which is a different take but very cool.</p></pre>gureggu: <pre><p>It's not code generation (it uses reflection), but the <a href="https://github.com/jmoiron/sqlx" rel="nofollow">sqlx package</a> lets you scan directly into structs (see ScanStruct), although I'm not a huge fan of its "add x to stuff" naming pattern.</p></pre>jmoiron: <pre><p>I'm not very creative.</p></pre>gureggu: <pre><p>No ill will intended! For what it's worth, I can't think of any better names :)</p></pre>kosokun: <pre><p>I like the names you picked for <code>sqlx</code>, they're concises.</p></pre>natefinch: <pre><p>I'm a big fan of sqlx, and have used it in the past. It's my default answer to "what ORM should I use?". While it handily removes the code to convert database/sql results to my structs, I still need to write a lot of braindead sql to use it, which is annoying.</p></pre>455_dsf_-4: <pre><p>It's possible for simple CRUD operations , but for more complex queries you'd need some kind of DSL first.</p>
<p>I think the best compromise would be an ORM with a query builder that can cache SQL queries. But it's a lot of work.</p>
<p>In practice, code generation becomes yet another dependency to manage in a project.</p></pre>cartesian_bear: <pre><p>We bit the bullet and started using <a href="https://github.com/go-gorp/gorp" rel="nofollow">gorp</a>, which turned out to be OK so far and cut down some SQL boilerplate. You can still write raw SQL with it. One thing to be aware of is that it doesn't like if you return columns that aren't in your target struct, so <code>select *</code> is frowned upon.</p></pre>23inhouse: <pre><p>My friend just wrote this library for one of our projects at work.</p>
<p><a href="https://github.com/waterlink/rebecca" rel="nofollow">https://github.com/waterlink/rebecca</a></p>
<p>It has some basic read and write functions. It looks like it's at the right level of simplicity to match golang.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传