uptrace / bun

SQL-first Golang ORM
https://bun.uptrace.dev
BSD 2-Clause "Simplified" License
3.65k stars 221 forks source link

Has Many Join on nullable value #950

Open comsma opened 8 months ago

comsma commented 8 months ago
type InventoryReceiptsLine struct {
    bun.BaseModel `bun:"table:inventory_receipts_line"`

    ReceiptNumber             float64         `bun:"receipt_number,type:decimal(19,0),pk"`
    InvMastUid                int32           `bun:"inv_mast_uid,type:int"`

    Ira []*InvTran `bun:"rel:has-many,join:receipt_number=sub_document_no,join:inv_mast_uid=inv_mast_uid,join:type=trans_type,polymorphic:IRA"`
}

type InvTran struct {
    bun.BaseModel `bun:"table:inv_tran"`

    TransType              string          `bun:"trans_type,type:varchar(5)"`
    SubDocumentNo   sql.NullFloat64 `bun:"sub_document_no,type:decimal(19,0),nullzero"`
    InvMastUid             int32           `bun:"inv_mast_uid,type:int"`
}

I am trying to join a list of transactions(InvTran) to InventoryReceiptsLine. Being that InvTran.SubDocumentNo is sql.NullFloat64 i get an error saying *errors.errorString: bun: has-many relation=Ira does not have base model=InventoryReceiptsLine with id=[{%!q(float64=5.17761e+06) %!q(bool=true)} '華'] (check join conditions).

How can i join these without changing the type of SubDocumentNo as these models are base on a active erp system in which i do not have control over the schema?

lazharichir commented 8 months ago

Oh wow, the timing is good. Exact same issue for me.

type Individual struct {
    bun.BaseModel  `bun:"individuals,alias:ind"`
    ID             string             `json:"ID" required:"true" bun:",pk"`
    WorkspaceID    string             `json:"WorkspaceID" required:"true"`
    HubspotObjects []*HubspotObject   `json:"HubspotObjects" bun:"rel:has-many,join:id=individual_id"`
}

type HubspotObject struct {
    bun.BaseModel  `bun:"hubspot_objects,alias:hso"`
    ID             string          `json:"ID" required:"true" bun:",pk"`
    WorkspaceID    string          `json:"WorkspaceID" required:"true"`
    IndividualID   *string         `json:"IndividualID"` // can be null
    OrganizationID *string         `json:"OrganizationID"` // can be null
    SyncedAt       *time.Time      `json:"SyncedAt"`
    UpdatedAt      time.Time       `json:"UpdatedAt" required:"true"`
    CreatedAt      time.Time       `json:"CreatedAt" required:"true"`
}

func (h *Handlers) SearchIndividuals() {
    ids := []string{"a", "z"}

    // load the individuals
    individuals := []entity.Individual{}
    if err := h.bun.NewSelect().
        Model(&individuals).
        Relation("HubspotObjects").
        Where("ind.id IN (?)", bun.In(ids)).
        Scan(ctx); err != nil {
        return nil, apperrors.SqlError(err, "search individuals")
    }
}

And it errors: errors.errorString: bun: has-many relation=HubspotObjects does not have base model=Individual with id=[%!q(*string=0x1400003d2b0)] (check join conditions)

jeffreydwalter commented 5 months ago

I am also having this problem with a custom type for my pk field, so ID *ids.ID. @vmihailenco are you still maintaining this project?

jeffreydwalter commented 5 months ago

@JunNishimura not sure who's reviewing PRs these days, but I pushed a fix for this, really need to get it merged asap. It's causing my company a lot of pain trying to migrate to bun.

comsma commented 5 months ago

I reverted to just doing a manual join on the table, I've only used it to fetch the base record when I need to do where clauses it might work for the nested records as well.

jeffreydwalter commented 5 months ago

@comsma that defeats the purpose of an ORM. My PR fixes the issue if you want to maintain your own fork until this gets merged.

jeffreydwalter commented 5 months ago

@JunNishimura PR is here.

JunNishimura commented 5 months ago

@jeffreydwalter Thanks for you contribution👍 Unfortunately, I'm not a maintainer of this repository, so I cannot approve your PR.

However, I will check to make sure that the PR you submitted is acceptable so that it can be approved ASAP.