小编rob*_*y22的帖子

使用Gorm插入和选择PostGIS Geometry

我一直试图找到一种方法来使用Golang插入和检索几何类型,特别是库gorm.我还尝试使用为几何定义不同类型的库orb,并提供不同格式之间的编码/解码.

天体具有Scan()Value()方法已经为每种类型的实现.这允许go Insert()Scan()函数使用基元以外的类型.然而,Orb期望使用以众所周知的二进制(WKB)格式表示的几何.

orb文档显示要完成此操作,您只需将字段包装在PostGIS函数中ST_AsBinary(),ST_GeomFromWKB()并分别进行查询和插入.例如,将表定义为:

_, err = db.Exec(`
        CREATE TABLE IF NOT EXISTS orbtest (
            id SERIAL PRIMARY KEY,
            name TEXT NOT NULL,
            geom geometry(POLYGON, 4326) NOT NULL
        );
    `)
Run Code Online (Sandbox Code Playgroud)

你可以这样做:

rows, err := db.Query("SELECT id, name, ST_AsBinary(geom) FROM orbtest LIMIT 1")
Run Code Online (Sandbox Code Playgroud)

对于insert(其中p是orb.Point):

db.Exec("INSERT INTO orbtest (id, name, geom) VALUES ($1, $2, ST_GeomFromWKB($3))", 1, "Test", wkb.Value(p))
Run Code Online (Sandbox Code Playgroud)

这是我的问题:通过使用GORM,我没有能够使用这些功能构建这些查询的奢侈.GORM将在给定结构的情况下自动将值插入数据库,并将数据扫描到结构的整个层次结构中.那些Scan()Value()方法在幕后被称为,没有我的控制.

尝试直接将二进制数据插入几何列中将不起作用,直接查询几何列将以十六进制形式给出结果.

我已经尝试了多种数据库方法来解决这个问题.我试图创建自动调用几何列上所需函数的视图.这适用于查询,但不能插入.

是否有可能制定某种触发器或规则来自动调用进/出数据所需的函数?

我还应该注意到,我正在处理的库完全独立于数据和模式,所以我没有任何类型的查询硬编码的奢侈.我当然可以编写一个扫描整个数据模型的函数,并从头开始生成查询,但我更喜欢有更好的选择. …

postgresql postgis go wkb go-gorm

8
推荐指数
2
解决办法
1030
查看次数

单元测试 sqlmock 因 sql 更新而失败

我们一直在使用 sqlmock 测试使用 select 的 func() - 没有问题。

它不适用于更新。

我们要测试的功能是:

func PutTag(tag *Tag) error {
...
    err = db.DB.Where("id=?", tag.Id).Save(tag).Error
...
}
Run Code Online (Sandbox Code Playgroud)

我们这样定义测试函数:

func (s *Suite) TestPutTag() {
    tag := Tag{Id: 2, Name: "Test Tag 2"}
    s.mock.ExpectBegin()
    s.mock.ExpectQuery("UPDATE `tags` SET `name` = ?  WHERE `tags`.`id` = ? AND ((id=?))").
        WithArgs(tag.Name, tag.Id, tag.Id)
    s.mock.ExpectCommit()
    err := PutTag(&tag)
    require.NoError(s.T(), err)
}
Run Code Online (Sandbox Code Playgroud)

这是回归..

[2019-08-30 14:36:36]  call to ExecQuery 'UPDATE `tags` SET `name` = ?  WHERE `tags`.`id` = ? AND ((id=?))' with args [{Name: …
Run Code Online (Sandbox Code Playgroud)

mysql unit-testing go go-gorm go-sqlmock

6
推荐指数
0
解决办法
1822
查看次数

如何使用 go-sql (postgres) 模拟 gorm 插入

我将Gorm与 postgresql 驱动程序一起使用。我尝试使用go-sqlmock模拟数据库插入:

type Test struct {
    FirstName string `json:"first_name"`
}

func (db *DB) CreateTest() (*Test, error) {
    test := Test{"c"}
    if result := db.Create(&test); result.Error != nil {
        return nil, result.Error
    }

    return &test, nil
}


func TestCreateUser(t *testing.T) {
    _, mock, _ := sqlmock.NewWithDSN("sqlmock_db_0")

    mockedGorm, _ := gorm.Open("sqlmock", "sqlmock_db_0")
    defer mockedGorm.Close()
    myDB := &DB{mockedGorm}

    mock.ExpectExec("INSERT INTO test").WithArgs("c").WillReturnResult(sqlmock.NewResult(1, 1))
    myDB.Exec("INSERT INTO test(first_name) VALUES (?)", "c")


    if _, err := myDB.CreateTest(); err != nil {
        t.Errorf("error …
Run Code Online (Sandbox Code Playgroud)

testing go go-gorm go-sqlmock

6
推荐指数
1
解决办法
6343
查看次数

使用GORM选择相关字段

我是来自python背景的Golang的新手,因此尝试了解新的和不同的概念。我正在尝试创建相关字段,然后从数据库中选择它们。

楷模:

type Company struct {
    gorm.Model
    Name string
}

type CreditCard struct {
    gorm.Model
    Number    int
    Company   Company
    CompanyId uint
}

type User struct {
    gorm.Model
    Name         string
    CreditCard   CreditCard
    CreditCardID uint
}
Run Code Online (Sandbox Code Playgroud)

创建表和行并从数据库中选择

common.DB.AutoMigrate(
    &Company{},
    &CreditCard{},
    &User{},
)

user := User{
    Name:       "Alice",
    CreditCard: CreditCard{Number: 123456, Company: Company{Name: "Bank A"}},
}

common.DB.Create(&user)

var retrivedUser User
var creditCard CreditCard
var company Company
common.DB.First(&retrivedUser, 1).Related(&creditCard).Related(&company)

fmt.Println("user name", retrivedUser.Name)
fmt.Println("creditcard number", retrivedUser.CreditCard.Number)
fmt.Println("creditcard number related", creditCard.Number)
fmt.Println("company name", retrivedUser.CreditCard.Company.Name)
fmt.Println("company name …
Run Code Online (Sandbox Code Playgroud)

go go-gorm

5
推荐指数
1
解决办法
316
查看次数

Gorm (Golang) 和带有单表继承“类型”列的数据库

我正在尝试使用 Go 从作为现有 Rails 应用程序一部分的数据库中读取数据。一些模型和表通过type列使用单表继承。在 Rails/ActiveRecord 中,此列的存在将创建到适当模型的自动映射。如果表是animals并且typeDog,它将映射到Dog类;如果是Cat,它将映射到Cat类。我想在 Gorm 中设置类似的东西。

由于看起来 Gorm 没有default_scope模型选项,我使用了一个新的回调。

func scopedSearch(scope *gorm.Scope) {
    tablename := scope.TableName()
    switch tablename {
    case "table_using_sti":
        scope.Search.Where("type = ?", "MyModelName")
    default:
        return
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我在我的main函数中注册回调:

db.Callback().Query().Before("gorm:query").Register("my_plugin:before_query", scopedSearch)
Run Code Online (Sandbox Code Playgroud)

当我搜索使用的实例db.First或使用的模型时db.Model(&MyModel{}).Where(...),它似乎正在工作。这是处理它的正确方法吗?所有查询方法都会遵守此范围还是有更直接或更彻底的方法?

go go-gorm

5
推荐指数
0
解决办法
695
查看次数

每次调用 gorm.Open() 时都会创建一个新的连接池吗?

我正在编写一段代码,该代码从几个不同的地方调用数据库。在这段代码中,我一直在使用 GORM 库,并在gorm.Open()每次需要与数据库交互时调用。

我想知道的是当我调用它时引擎盖下发生了什么?每次调用时都会创建一个新的连接池,还是每次调用都gorm.Open()共享同一个连接池?

mysql go go-gorm

5
推荐指数
3
解决办法
5953
查看次数

如何删除gorm包的Create方法中的RETURNING子句?

在为gorm包创建记录时,我对默认行为有点困惑。

city := models.City

if err := databases.DBGORM.Set("gorm:insert_option", "RETURNING *").Create(&city).Error; err != nil {
    fmt.Println(err.Error())
}
Run Code Online (Sandbox Code Playgroud)

在日志中,我看到这样的 SQL 查询:

INSERT INTO "my_scheme"."city" ("created_at","updated_at","deleted_at","name","country") VALUES ('2020-05-19 23:45:18','2020-05-19 23:45:18',NULL,'New York','USA') RETURNING * RETURNING "my_scheme"."city"."id"
Run Code Online (Sandbox Code Playgroud)

正如您从查询中看到的,我有一个RETURNING不正确的双子句并引发错误。

id在 SQL 查询的末尾添加似乎是该Create方法的默认行为。我怎样才能改变这种行为?

模型.去

package models

import (
    "my_app/proto"
    "time"
)

type City struct {
    Id uint64
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt *time.Time
    proto.City
}

func (City) TableName() string {
    return "my_scheme.city"
}
Run Code Online (Sandbox Code Playgroud)

sql go go-gorm

5
推荐指数
1
解决办法
300
查看次数

不支持的数据类型:GORM 字段上的 &[] 错误,其中自定义 Valuer 返回 nil?

我试图创建一个Postgres数据库一GORM模型,含有一种具有自定义Scanner,并Valuer认为将字符串转换为切片,并从一个字符串,保存为一个单一的数据库列。如果切片为空或 nil,我希望数据库列也为零(而不是空字符串)。

type MultiString []string

func (s *MultiString) Scan(src interface{}) error {
    str, ok := src.(string)
    if !ok {
        return errors.New("failed to scan multistring field - source is not a string")
    }
    *s = strings.Split(str, ",")
    return nil
}

func (s MultiString) Value() (driver.Value, error) {
    if s == nil || len(s) == 0 {
        return nil, nil
    }
    return strings.Join(s, ","), nil
}
Run Code Online (Sandbox Code Playgroud)

当我尝试调用AutoMigrate以下结构时出现问题:

type Person struct {
    ID      int
    Name    string
    Kids …
Run Code Online (Sandbox Code Playgroud)

postgresql go go-gorm

5
推荐指数
1
解决办法
4793
查看次数

standard_init_linux.go:228: exec 用户进程导致:CGO 项目上没有这样的文件或目录

我有一个引用 C 库的 Go 服务,在尝试运行我的 docker 映像时收到以下错误:

standard_init_linux.go:228: exec user process caused: no such file or directory

这不是standard_init_linux.go:190: exec 用户进程导致“没有这样的文件或目录”的重复 - Docker,因为我没有带有 CR 行结尾的入口点 shell 脚本。该网站上的其他一些人建议CGO_ENABLED=0在编译时进行设置,但我当然不能这样做,因为这是一个 CGO 项目。

C 库安装在和/usr/local/lib/sgp4目录下,其中包含一堆 .so 文件。Linux/IFORTLinux/GFORTRAN

环境变量 LD_LIBRARY_PATH 设置为 /usr/local/lib/sgp4/Linux/IFORT。

在我的项目中,有一组包装器.h文件,CGO注释如下:

去设置

我的 Dockerfile 如下:

FROM [redacted]/alpine-base:3.17

RUN apk update && \
    apk add curl jq

COPY etc/cfg/propagator.properties /usr/local/[redacted]/etc/cfg/
COPY bin/sgp4 /usr/local/[redacted]/bin/sgp4
COPY propagator/wrappers /usr/local/[redacted]/bin/wrappers

# Download library files
RUN mkdir -p /usr/local/sgp4/lib
RUN curl --output /usr/local/sgp4/lib/SGP4.tar …
Run Code Online (Sandbox Code Playgroud)

c go cgo docker dockerfile

5
推荐指数
1
解决办法
231
查看次数

Go 单元测试 - 调用数据库事务开始,出现意外错误

我正在尝试使用 Data Doggo-sqlmock和.Go 编写模型单元测试testify

我有以下代码:

type Suite struct {
    suite.Suite
    DB *gorm.DB
    mock sqlmock.Sqlmock

    repository      Repository
    user *models.User
}

func (s *Suite) SetupSuite() {
    var (
        db  *sql.DB
        err error
    )

    db, s.mock, err = sqlmock.New()
    require.NoError(s.T(), err)

    s.DB, err = gorm.Open("mysql", db)
    require.NoError(s.T(), err)

    s.DB.LogMode(true)

    s.repository = CreateRepository(s.DB)
}

func (s *Suite) AfterTest(_, _ string) {
    require.NoError(s.T(), s.mock.ExpectationsWereMet())
}

func TestInit(t *testing.T) {
    suite.Run(t, new(Suite))
}

func (s *Suite) Test_repository_Get() {
    var (
        ID        = …
Run Code Online (Sandbox Code Playgroud)

go testify go-gorm go-sqlmock

4
推荐指数
1
解决办法
2万
查看次数

标签 统计

go ×10

go-gorm ×9

go-sqlmock ×3

mysql ×2

postgresql ×2

c ×1

cgo ×1

docker ×1

dockerfile ×1

postgis ×1

sql ×1

testify ×1

testing ×1

unit-testing ×1

wkb ×1