I need help understanding this error. The code works with sqlite. The ? looks like the sql package is not even putting a value there but sending the question mark as is.
I can run other select statements without issues so its not a connection problem or something like that.
Error: Incorrect syntax near '?'
func TestSQLServerInsert(t *testing.T) {
db, err := sql.Open("sqlserver", "my_trusted_string")
//db, err := sql.Open("sqlite3", "../data/utm_info.db")
if err != nil {
t.Errorf("could not open database: %v", err)
}
defer db.Close()
c := controller.NewC(db)
u := controller.UtilizationResponse{
Snapshot: []int{46, 22, 4, 4, 5, 3, 0, 8, 49},
History: []float32{55.1, 47.2, 0.3, 33.4, 23.5},
Time: time.Now(),
}
affectedRows, err := c.InsertUtil(u)
if err != nil {
t.Errorf("could not insert into db: %v", err)
}
var count int64 = 1
assert.Equal(t, affectedRows, count)
}
// InsertUtil response inserts a new record into the database
func (c *Controller) InsertUtil(u UtilizationResponse) (rowsAffected int64, err error) {
return insertUtil(c.DB, u)
}
func insertUtil(db *sql.DB, u UtilizationResponse) (int64, error) {
stmt, err := db.Prepare("INSERT INTO Utilization VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")
if err != nil {
return 0, err
}
res, err := stmt.Exec(
u.Time,
u.Snapshot[0],
u.Snapshot[1],
u.Snapshot[2],
u.Snapshot[3],
u.Snapshot[4],
u.Snapshot[5],
u.Snapshot[6],
u.Snapshot[7],
u.Snapshot[8],
u.History[0],
u.History[1],
u.History[2],
u.History[3],
u.History[4],
)
if err != nil {
return 0, err
}
rowCnt, err := res.RowsAffected()
if err != nil {
return 0, err
}
return rowCnt, nil
}
type UtilizationResponse struct {
Snapshot []int `json:"snapshot,omitempty"`
History []float32 `json:"history,omitempty"`
Time time.Time `json:"time,omitempty"`
}
The sqlserver driver uses normal MS SQL Server syntax and expects parameters in the sql query to be in the form of either #Name or #p1 to #pN (ordinal position).
insertSql := "insert into test (id, idstr) values (#p1, #p2)"
After some testing, I can confirm it works. It even works with sqlite3 so this seems to be a more widely accepted way.
Related
I have written following code to get the daily maximum of a certain value with GORM.
I pass the current time and get the day's start and end.
I select all values between the day's start and end.
I order the temperatures and get the first.
My Code:
func GetDailyMaxTemperature(ts time.Time) (*Temperature, error) {
temp:= &Temperature{}
start, end := getStartAndEndOfDay(ts)
if tx := db.Where("ts BETWEEN ? AND ?", start, end).Order("temperature ASC").First(temp); tx.Error != nil {
return temp, tx.Error
}
return temp, nil
func getStartAndEndOfDay(ts time.Time) (time.Time, time.Time) {
dayStart := time.Date(ts.Year(), ts.Month(), ts.Day(), 0, 0, 0, 0, ts.Location())
dayEnd := time.Date(ts.Year(), ts.Month(), ts.Day(), 23, 59, 59, 999, ts.Location())
return dayStart, dayEnd
}
This code works, however I am not very satisfied with it and wonder if there are more "GORM-ish" ways to get a maximum value of a certain table especially when there are dates involved.
You could use the max operation in SQL. Maybe not a more 'GORM' way to do this, but in my opinion a more semantically correct/appealing version:
var result float64
row := db.Table("temperatures").Where("ts BETWEEN ? AND ?", start, end).Select("max(temperature)").Row()
err := row.Scan(&result)
You could make this a method of the Temperature struct like this:
func (t Temperature) MaxInRange(db *gorm.DB, start, end time.Time) (float64, err) {
var result float64
row := db.Table("temperatures").Where("ts BETWEEN ? AND ?", start, end).Select("max(temperature)").Row()
err := row.Scan(&result)
return result, err
}
I have a Go app that connects with a postgres database through the driver called "github.com/lib/pq".
I make a connection with a database called godb, and the function Open() works correctly, but when I check errors with db.Ping(), it tells me the database doesn´t exist, although I have created it in pg Admin and the name and the password are well written. I have tried to check if the connection string is correct, I have tried to create a new database and connect it but it gives the same error. I have also tried to disconnect and reconnect the database and it doesn't work.
package main
import (
"database/sql"
"fmt"
"log"
"sync"
//driver of the database
_ "github.com/lib/pq"
)
var (
db *sql.DB
once sync.Once
)
func NewPostgresDB() {
once.Do(func() {
var err error
db, err = sql.Open("postgres",
"postgres://postgres:/*password of the database*/#localhost:5432/godb?sslmode=disable")
if err != nil {
log.Fatalf("There is an error in the connction string %v", err)
}
if err = db.Ping(); err != nil {
log.Fatalf("There was an error connecting to the database %v", err)
}
})
fmt.Println("connection succeeded")
}
this is the error it exactly returns (it's in Spanish):
pq: no existe la base de datos �godb�
exit status 1
I do not understand how to add recording parameters for MongoDB using mongo-go-driver
Example request
c.client.Database(MONGO_DATABASE).Collection(*packet.ID).InsertMany(nil, packet.Item, opt)
How to specify the necessary parameters in opt?
VERSION 1.0
In MongoDB Go driver production release you can set writeConcern as below:
import (
"go.mongodb.org/mongo-driver/mongo/options"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/writeconcern"
)
mongoURI := "mongodb://server:port/"
opts := options.Client().ApplyURI(mongoURI).SetWriteConcern(writeconcern.New(writeconcern.WMajority()))
client, err := mongo.NewClient(opts)
if err != nil {
panic(err)
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err = client.Connect(ctx)
if err != nil {
panic(err)
}
collection := client.Database("database").Collection("collection")
See also:
mongo-driver/mongo/options
mongo-driver/mongo/writeconcern
VERSION 0.0.16
Using mongo-go-driver, you can set a write concern option as below example:
import(
"github.com/mongodb/mongo-go-driver/bson"
"github.com/mongodb/mongo-go-driver/core/writeconcern"
"github.com/mongodb/mongo-go-driver/mongo"
"github.com/mongodb/mongo-go-driver/mongo/collectionopt"
)
// Example document
document := bson.VC.DocumentFromElements(
bson.EC.SubDocumentFromElements(
"foo",
bson.EC.Int32("bar", 101),
),
)
// Set majority write concern
wMajority := writeconcern.New(writeconcern.WMajority())
database := client.Database("database")
collection := database.Collection("collection", collectionopt.WriteConcern(wMajority))
_, err = collection.InsertOne(context.Background(), document)
Can also use W(int) to specify an arbitrary number of mongod instances. See more writeconcern/writeconcern.go
I'm having issues setting the timeout in go-mssqldb
This is my current connection string:
sqlserver://user:password#server?timeout=1m30s
I can connect just fine, run queries etc. but I keep timing out at the default value of 30 seconds.
I'm referencing the documentation here.
What am I missing?
import (
"database/sql"
_ "github.com/denisenkom/go-mssqldb"
)
func main(){
db, err := sql.Open("mssql", "sqlserver://user:password#server?timeout=1m30s")
if err != nil{
panic(err)
}
_, err = db.Exec("run query that takes longer than 30 seconds")
if err != nil{
panic(err)
}
// panic at 30 seconds...
// panic: read tcp {my ip}->{server ip}: i/o timeout
}
I was referencing the wrong documentation initially. To format the url see the following:
"sqlserver://user:password#server?connection+timeout=90"
Iteration to datastore query result in GAE/Go is very slow.
q := datastore.NewQuery("MyStruct")
gaeLog.Infof(ctx, "run") // (1)
it := client.Run(ctx, q)
list := make([]MyStruct, 0, 10000)
gaeLog.Infof(ctx, "start mapping") // (2)
for {
var m MyStruct
_, err := it.Next(&m)
if err == iterator.Done {
break
}
if err != nil {
gaeLog.Errorf(ctx, "datastore read error : %s ", err.Error())
<some error handling>
break
}
list = append(list , m)
}
gaeLog.Infof(ctx, "end mapping. count : %d", len(list)) // (3)
The result is below.
18:02:11.283 run // (1)
18:02:11.291 start mapping // (2)
18:02:15.741 end mapping. count : 2400 // (3)
It takes about 4.5 seconds between (2) and (3), just only 2400 record. It is very slow.
How can I improve performance?
[Update]
I added the query in above code q := datastore.NewQuery("MyStruct").
I tried to retrieve all the entities in the kind MyStruct. This kind has 2400 entities.
I was using cloud.google.com/go/datastore and found it is slow. I migrated to use google.golang.org/appengine/datastore.
The result is as follows, less than 1 second.
13:57:46.216 run
13:57:46.367 start mapping
13:57:47.063 end mapping. count : 2400