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

Import full distant schema and store in remote server #5211

Merged
merged 5 commits into from
Apr 30, 2024

Conversation

thomtrp
Copy link
Contributor

@thomtrp thomtrp commented Apr 29, 2024

We should not depend on the foreign data wrapper type to manage distant table. The remote server should be enough to handle the table creation.

Here is the new flow to fetch available tables:

  • check if the remote server have available tables already stored
  • if not, import full schema in a temporary schema
  • copy the tables into the available tables field
  • delete the schema

Left todo:

  • update remote server input for postgres so we receive the schema

Copy link

github-actions bot commented Apr 29, 2024

TODOs/FIXMEs:

  • // TODO: return error to the user when a column cannot be managed: packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.service.ts
  • // TODO: function should work for other types than Postgres: packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.service.ts
  • // TODO: function should work for other types than Postgres: packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.service.ts
  • // TODO: function should work for other types than Postgres: packages/twenty-server/src/engine/metadata-modules/remote-server/remote-table/remote-table.service.ts

Generated by 🚫 dangerJS against 42c923a

Copy link
Member

@Weiko Weiko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments @thomtrp

remoteServer: RemoteServerEntity<RemoteServerType>,
workspaceId: string,
): Promise<string[]> {
if (!remoteServer.schema) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where we ask the schema name from the UI. Is it planned for an upcoming UI? Currently it's failing with this check

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I wouldn't throw an "Error" here, this does not seem to be internal issue but more tied to the user input and we don't want to capture such exceptions to Sentry for example.
Can you throw a BadRequestException? Ideally in the future we will have specific exceptions internal to twenty and not tied to REST/Graphql implementations but in the meantime let's use that!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally in the future we will have specific exceptions internal to twenty and not tied to REST/Graphql implementations but in the meantime let's use that!

cc @charlesBochet 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting on @ijreilly's work to add the schema as input!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally added it in this PR

@@ -181,14 +175,14 @@ export class RemoteTableService {
localTableName,
input,
remoteServer,
remoteTableColumns,
distantTableColumns,
);

await this.createRemoteTableMetadata(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in a transaction to avoid having a foreign table created without metadata

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this requires a refacto that should not be done in this PR IMO. The service fieldMetadataService is doing a transaction for each creation. We would need to send a manager as input so it uses it when defined

case RemoteServerType.POSTGRES_FDW:
return FeatureFlagKeys.IsPostgreSQLIntegrationEnabled;
default:
throw new BadRequestException('PostgreSQL integration is not enabled');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is the right error message here. Should probably be ${remoteServerType} integration is not supported or something, you check postgresql integration above already

case 'int4':
return FieldMetadataType.NUMBER;
default:
return FieldMetadataType.TEXT;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should throw here instead to avoid side effects with unhandled types

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. We would throw often, but at least we will know when a type is not supported. Will do in another PR, I should look for all types available

// TODO: return error to the user when a column cannot be managed
try {
const field = await this.fieldMetadataService.createOne({
name: column.columnName,
Copy link
Member

@Weiko Weiko Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To check if this works with column names with snake_case, I believe this is rejected as of today (you can try by calling a column "created_at" in your distant DB) to be compliant with graphql type names

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the logic to use camelCase !

Copy link
Member

@Weiko Weiko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good job 👏 @thomtrp

@Weiko Weiko merged commit 3a61c92 into main Apr 30, 2024
9 of 10 checks passed
@Weiko Weiko deleted the tt-import-schema-for-postgres branch April 30, 2024 12:18
arnavsaxena17 pushed a commit to arnavsaxena17/twenty that referenced this pull request Oct 6, 2024
We should not depend on the foreign data wrapper type to manage distant
table. The remote server should be enough to handle the table creation.

Here is the new flow to fetch available tables:
- check if the remote server have available tables already stored
- if not, import full schema in a temporary schema
- copy the tables into the available tables field 
- delete the schema

Left todo:
- update remote server input for postgres so we receive the schema

---------

Co-authored-by: Thomas Trompette <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants