Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defining entities with relationships that have overlapping columns with different nullability #4478

Closed
dorcastan opened this issue Jun 22, 2023 · 4 comments
Labels
enhancement New feature or request

Comments

@dorcastan
Copy link

Is your feature request related to a problem? Please describe.

Is there a way to define entities where a column is part of multiple foreign keys / relationships, but one relationship is optional and the other is required?

Desired schema:

create table "student_allocation" (
  "student_id" text not null,
  "academic_year" text not null,
  "school_code" text not null references "school" ("school_code"),
  "class_code" text null,
  constraint "student_allocation_pkey" primary key ("student_id", "academic_year")
);

alter table "student_allocation" add constraint "student_allocation_class_foreign"
foreign key ("school_code", "academic_year", "class_code") references "class" ("school_code", "academic_year", "class_code");
  • (Context: The app uses natural keys. A student may be assigned to a school but not have a class yet, hence both relationships are necessary.)

Current behaviour: When defining the optional relationship, all columns (including school_code and academic_year) are marked as nullable. Moving the school property after class "fixes" the issue for school_code, but this doesn't work for academic_year.

Sample code:

import { Entity, ManyToOne, PrimaryKey, PrimaryKeyType } from '@mikro-orm/core';

@Entity()
class School {
  @PrimaryKey()
  schoolCode: string;
}

@Entity()
class Class {
  [PrimaryKeyType]: [string, string, string];

  @PrimaryKey({ name: 'school_code' })
  school: School;

  @PrimaryKey()
  academicYear: string;

  @PrimaryKey()
  classCode: string;
}

@Entity()
export class StudentAllocation {
  [PrimaryKeyType]: [string, string];

  @PrimaryKey()
  studentId: string;

  @PrimaryKey()
  academicYear: string;

  @ManyToOne({ name: 'school_code' })
  school: School;

  // TODO: this overwrites the nullability of school_code and academic_year -- both columns are set to nullable.
  @ManyToOne({ fieldNames: ['school_code', 'academic_year', 'class_code'] })
  class?: Class;
}

Describe the solution you'd like

My understanding from #593 (comment) that this isn't a feature supported by MikroORM --

you can't have 2 properties on your entity that represent same column (parentEntity vs parentEntityKey are in fact one column but you are modelling it as two).

Is there a recommended way to address this use case?

Alternatively, would it be possible to add a flag to make the schema generator ignore the relationship entirely? e.g. modify ignoreSchemaChanges to apply to foreign keys.

  • Desired behaviour: once the DB migration has been manually fixed, no further schema changes will be flagged out.
  @ManyToOne({
    fieldNames: ['school_code', 'academic_year', 'class_code'],
    ignoreSchemaChanges: ['type'] 
  })
  class?: Class;
@dorcastan dorcastan added the enhancement New feature or request label Jun 22, 2023
@B4nan
Copy link
Member

B4nan commented Jun 22, 2023

you can't have 2 properties on your entity that represent same column (parentEntity vs parentEntityKey are in fact one column but you are modelling it as two).

I want to look into lifting this restriction in v6, not sure if we have an open issue for that, so let's keep this one.

@B4nan B4nan added this to the 6.0 milestone Jun 22, 2023
@dorcastan
Copy link
Author

Thanks for the speedy reply!

Is there any early indication / target date for when v6 will be released?

@B4nan
Copy link
Member

B4nan commented Jun 22, 2023

Not really, I am kinda almost there, but it's hard to find some time to work on it during summer, and I still have some rather challenging refactors I want to do (or at least give it a try). And then there are the outdated docs and the new getting started guide.

But v6 is already published to NPM on each commit to v6 branch, and is generally usable. The upgrading guide is here:

https://github.com/mikro-orm/mikro-orm/blob/v6/docs/docs/upgrading-v5-to-v6.md

@B4nan B4nan removed this from the 6.0 milestone Sep 29, 2023
@B4nan
Copy link
Member

B4nan commented Sep 29, 2023

This can be actually fixed in v5, it's pretty simple in the end.

@B4nan B4nan closed this as completed in 208fbaa Sep 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants