diff --git a/README.md b/README.md index da7ed91..eeeb859 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,31 @@ This is a [Singer](https://singer.io) target for Postgres following the [Singer spec](https://github.com/singer-io/getting-started/blob/master/SPEC.md). +#### Samle config: + + { + "host": "localhost", + "user": "test", + "port": "5432", + "password": "", + "dbname": "target_test", + "schema": "test_schema" + } + +#### Mandatory properties: + +`host`: The host name of the PostgreSQL server + +`user`: The database user on whose behalf the connection is being made. + +`port`: The port number the server is listening on + +`password`: The database user's password. + +`dbname`: The database name + +`schema`: Destination schema name + +#### Optional properties: + +`grant_select_to`: String or Array. When a new schema or table is created, SELECT privilege will be granted to one or more ROLEs automatically. diff --git a/target_postgres/db_sync.py b/target_postgres/db_sync.py index 4fba051..7bd2089 100644 --- a/target_postgres/db_sync.py +++ b/target_postgres/db_sync.py @@ -257,6 +257,23 @@ def create_table_query(self, is_temporary=False): ', '.join(columns + primary_key) ) + def grant_usage_on_schema(self, schema_name, grantee): + query = "GRANT USAGE ON SCHEMA {} TO GROUP {}".format(schema_name, grantee) + logger.info("Granting USAGE privilegue on '{}' schema to '{}'... {}".format(schema_name, grantee, query)) + self.query(query) + + def grant_select_on_all_tables_in_schema(self, schema_name, grantee): + query = "GRANT SELECT ON ALL TABLES IN SCHEMA {} TO GROUP {}".format(schema_name, grantee) + logger.info("Granting SELECT ON ALL TABLES privilegue on '{}' schema to '{}'... {}".format(schema_name, grantee, query)) + self.query(query) + + def grant_privilege(self, schema, grantees, grant_method): + if isinstance(grantees, list): + for grantee in grantees: + grant_method(schema, grantee) + elif isinstance(grantees, str): + grant_method(schema, grantees) + def create_schema_if_not_exists(self): schema_name = self.connection_config['schema'] schema_rows = self.query( @@ -265,7 +282,13 @@ def create_schema_if_not_exists(self): ) if len(schema_rows) == 0: - self.query("CREATE SCHEMA IF NOT EXISTS {}".format(schema_name)) + query = "CREATE SCHEMA IF NOT EXISTS {}".format(schema_name) + logger.info("Schema '{}' does not exist. Creating... {}".format(schema_name, query)) + self.query(query) + + if 'grant_select_to' in self.connection_config: + grant_select_to = self.connection_config['grant_select_to'] + self.grant_privilege(schema_name, grant_select_to, self.grant_usage_on_schema) def get_tables(self): return self.query( @@ -328,6 +351,10 @@ def sync_table(self): query = self.create_table_query() logger.info("Table '{}' does not exist. Creating... {}".format(stream, query)) self.query(query) + + if 'grant_select_to' in self.connection_config: + grant_select_to = self.connection_config['grant_select_to'] + self.grant_privilege(self.schema_name, grant_select_to, self.grant_select_on_all_tables_in_schema) else: logger.info("Table '{}' exists".format(stream)) self.update_columns()