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

Disable automatic column selection #427

Closed
jshearer opened this issue Mar 27, 2020 · 3 comments
Closed

Disable automatic column selection #427

jshearer opened this issue Mar 27, 2020 · 3 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@jshearer
Copy link

Is your feature request related to a problem? Please describe.
I'm trying to disable the selection of a specific column from queries by default. My specific usecase is a large text column that I'd love to only query when I really need to, though users in the TypeORM repo have talked about wanting to prevent selecting a password column (though they really shouldn't be storing passwords in plaintext anyway so I'm not sure why this matters).

Describe the solution you'd like
Initially I looked to see if I could pass a selected: false property to @Property, but then I realized that this would mean that I wouldn't actually have a good way to access the column when I want it. I believe TypeORM's solution is to transparently turn the field into an async-getter (i.e a getter that returns a Promise), which... might be a solution here? Something like this?

@Property({select: false})
long_text: Promise<string>;

Though working with raw promises like that seems somewhat confusing (does the promise run when the object is loaded, or just when I await it?), and doesn't seem coherent with the design of this library.

One thought I had is to treat this similarly to Reference fields (or maybe a special case Reference?), and in fact, I considered just making this a one-to-one reference: when I want to load long_text, I can just call await long_text.load().

@jshearer jshearer added the enhancement New feature or request label Mar 27, 2020
@B4nan
Copy link
Member

B4nan commented Mar 28, 2020

Having simple 1:1 relation is something I would do myself (with current orm version), but that is a bit different use case where you are designing the schema yourself, not when you work with an existing one.

You could also use fields option (FindOptions/FindOneOptions) to specify what you want to load, but it's a positive list, not list of exceptions. Although you could use entity metadata to construct the list of properties quite easily:

const meta = em.getMetadata().get('Author');
const blacklist = ['longText', ...]; // names of actual properties in entity definition, not table columns
const fields = Object.keys(meta.properties).filter(prop => !blacklist.includes(prop));
const authors = await em.find(Author, { ... }, { fields });

Sure we can add select: false to ease this. I am not sure about the promise getter idea though. It could work but it would produce 1 query for 1 entity. Will need to experiment a bit with that.

@jshearer
Copy link
Author

Since I am designing this myself I ended up going with the 1:1 approach and it's working fine.

I also agree about the promise getter. Having select: false influence the default EntityManager fields would be neat. I guess this would conceptually be similar to how eager works, but for columns instead of relations (and having the opposite effect).

@B4nan B4nan added this to the 4.0 milestone May 23, 2020
@B4nan B4nan self-assigned this May 23, 2020
@B4nan B4nan mentioned this issue May 23, 2020
46 tasks
B4nan added a commit that referenced this issue May 24, 2020
B4nan added a commit that referenced this issue May 24, 2020
B4nan added a commit that referenced this issue May 24, 2020
You can mark any property as `lazy: true` to omit it from the select clause.
This can be handy for properties that are too large and you want to have them
available only some times, like a full text of an article.

```typescript
@entity()
export class Book {

  @Property({ columnType: 'text', lazy: true })
  text: string;

}
```

You can use `populate` parameter to load them.

```typescript
const b1 = await em.find(Book, 1); // this will omit the `text` property
const b2 = await em.find(Book, 1, { populate: ['text'] }); // this will load the `text` property
```

> If the entity is already loaded and you need to populate a lazy scalar property,
> you might need to pass `refresh: true` in the `FindOptions`.

Closes #427
B4nan added a commit that referenced this issue May 24, 2020
You can mark any property as `lazy: true` to omit it from the select clause.
This can be handy for properties that are too large and you want to have them
available only some times, like a full text of an article.

```typescript
@entity()
export class Book {

  @Property({ columnType: 'text', lazy: true })
  text: string;

}
```

You can use `populate` parameter to load them.

```typescript
const b1 = await em.find(Book, 1); // this will omit the `text` property
const b2 = await em.find(Book, 1, { populate: ['text'] }); // this will load the `text` property
```

> If the entity is already loaded and you need to populate a lazy scalar property,
> you might need to pass `refresh: true` in the `FindOptions`.

Closes #427
B4nan added a commit that referenced this issue May 24, 2020
You can mark any property as `lazy: true` to omit it from the select clause. 
This can be handy for properties that are too large and you want to have them 
available only some times, like a full text of an article.

```typescript
@entity()
export class Book {

  @Property({ columnType: 'text', lazy: true })
  text: string;

}
``` 

You can use `populate` parameter to load them.

```typescript
const b1 = await em.find(Book, 1); // this will omit the `text` property
const b2 = await em.find(Book, 1, { populate: ['text'] }); // this will load the `text` property
```

> If the entity is already loaded and you need to populate a lazy scalar property, 
> you might need to pass `refresh: true` in the `FindOptions`.

Closes #427
@B4nan
Copy link
Member

B4nan commented May 24, 2020

Closing as implemented in dev branch via #585, subscribe to #527 for updates.

@B4nan B4nan closed this as completed May 24, 2020
B4nan added a commit that referenced this issue Jun 1, 2020
You can mark any property as `lazy: true` to omit it from the select clause. 
This can be handy for properties that are too large and you want to have them 
available only some times, like a full text of an article.

```typescript
@entity()
export class Book {

  @Property({ columnType: 'text', lazy: true })
  text: string;

}
``` 

You can use `populate` parameter to load them.

```typescript
const b1 = await em.find(Book, 1); // this will omit the `text` property
const b2 = await em.find(Book, 1, { populate: ['text'] }); // this will load the `text` property
```

> If the entity is already loaded and you need to populate a lazy scalar property, 
> you might need to pass `refresh: true` in the `FindOptions`.

Closes #427
B4nan added a commit that referenced this issue Jun 5, 2020
You can mark any property as `lazy: true` to omit it from the select clause. 
This can be handy for properties that are too large and you want to have them 
available only some times, like a full text of an article.

```typescript
@entity()
export class Book {

  @Property({ columnType: 'text', lazy: true })
  text: string;

}
``` 

You can use `populate` parameter to load them.

```typescript
const b1 = await em.find(Book, 1); // this will omit the `text` property
const b2 = await em.find(Book, 1, { populate: ['text'] }); // this will load the `text` property
```

> If the entity is already loaded and you need to populate a lazy scalar property, 
> you might need to pass `refresh: true` in the `FindOptions`.

Closes #427
B4nan added a commit that referenced this issue Jun 16, 2020
You can mark any property as `lazy: true` to omit it from the select clause. 
This can be handy for properties that are too large and you want to have them 
available only some times, like a full text of an article.

```typescript
@entity()
export class Book {

  @Property({ columnType: 'text', lazy: true })
  text: string;

}
``` 

You can use `populate` parameter to load them.

```typescript
const b1 = await em.find(Book, 1); // this will omit the `text` property
const b2 = await em.find(Book, 1, { populate: ['text'] }); // this will load the `text` property
```

> If the entity is already loaded and you need to populate a lazy scalar property, 
> you might need to pass `refresh: true` in the `FindOptions`.

Closes #427
B4nan added a commit that referenced this issue Aug 2, 2020
You can mark any property as `lazy: true` to omit it from the select clause. 
This can be handy for properties that are too large and you want to have them 
available only some times, like a full text of an article.

```typescript
@entity()
export class Book {

  @Property({ columnType: 'text', lazy: true })
  text: string;

}
``` 

You can use `populate` parameter to load them.

```typescript
const b1 = await em.find(Book, 1); // this will omit the `text` property
const b2 = await em.find(Book, 1, { populate: ['text'] }); // this will load the `text` property
```

> If the entity is already loaded and you need to populate a lazy scalar property, 
> you might need to pass `refresh: true` in the `FindOptions`.

Closes #427
B4nan added a commit that referenced this issue Aug 9, 2020
You can mark any property as `lazy: true` to omit it from the select clause. 
This can be handy for properties that are too large and you want to have them 
available only some times, like a full text of an article.

```typescript
@entity()
export class Book {

  @Property({ columnType: 'text', lazy: true })
  text: string;

}
``` 

You can use `populate` parameter to load them.

```typescript
const b1 = await em.find(Book, 1); // this will omit the `text` property
const b2 = await em.find(Book, 1, { populate: ['text'] }); // this will load the `text` property
```

> If the entity is already loaded and you need to populate a lazy scalar property, 
> you might need to pass `refresh: true` in the `FindOptions`.

Closes #427
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