Skip to content

Commit

Permalink
Add reg_reader creation
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartmcalpine committed Nov 24, 2023
1 parent 593c453 commit 12f63d7
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 132 deletions.
20 changes: 13 additions & 7 deletions scripts/create_registry_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from sqlalchemy import Column, Integer, String, DateTime, Boolean, Index, Float
from sqlalchemy import ForeignKey, UniqueConstraint, text
from sqlalchemy.orm import relationship, declarative_base
from dataregistry.db_basic import DbConnection, TableCreator, SCHEMA_VERSION
from dataregistry.db_basic import DbConnection, SCHEMA_VERSION
from dataregistry.db_basic import add_table_row, _insert_provenance

"""
Expand Down Expand Up @@ -234,10 +234,7 @@ def _Dependency(schema, has_production):
Integer,
ForeignKey(_get_ForeignKey_str("production", "dataset", "dataset_id")),
)

# #if SCHEMA != "production":
# # table1 = relationship('production.dataset', foreign_keys=[input_id_production])


# Table metadata
meta = {"__tablename__": "dependency", "__table_args__": {"schema": schema}}

Expand Down Expand Up @@ -281,12 +278,21 @@ def _Dependency(schema, has_production):
SCHEMA_LIST.remove("production")

# Create the schemas
acct = "reg_reader"
for SCHEMA in SCHEMA_LIST:
if SCHEMA is None:
continue
stmt = f"CREATE SCHEMA IF NOT EXISTS {SCHEMA}"
with db_connection.engine.connect() as conn:
# Create schema
stmt = f"CREATE SCHEMA IF NOT EXISTS {SCHEMA}"
conn.execute(text(stmt))

# Grant reg_reader access
usage_priv = f"GRANT USAGE ON SCHEMA {SCHEMA} to {acct}"
select_priv = f"GRANT SELECT ON ALL TABLES IN SCHEMA {SCHEMA} to {acct}"
conn.execute(text(usage_priv))
conn.execute(text(select_priv))

conn.commit()

# Create the tables
Expand All @@ -301,8 +307,8 @@ def _Dependency(schema, has_production):
# Generate the database
Base.metadata.create_all(db_connection.engine)

# Add initial procenance information
for SCHEMA in SCHEMA_LIST:
# Add initial procenance information
prov_id = _insert_provenance(
DbConnection(args.config, SCHEMA),
_DB_VERSION_MAJOR,
Expand Down
125 changes: 0 additions & 125 deletions src/dataregistry/db_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
__all__ = [
"DbConnection",
"add_table_row",
"TableCreator",
"TableMetadata",
"SCHEMA_VERSION",
]
Expand Down Expand Up @@ -154,130 +153,6 @@ def schema(self):
return self._schema


class TableCreator:
def __init__(self, db_connection):
"""
Make it easy to create one or more tables
Parameters
----------
dbConnection : a DbConnection object
"""
self._engine = db_connection.engine
self._schema = db_connection.schema
self._dialect = db_connection.dialect
self._metadata = MetaData(schema=db_connection.schema)

def define_table(self, name, columns, constraints=[]):
"""
Usual case: caller wants to create a collection of tables all at once
so just stash definition in MetaData object.
Parameters
----------
name : str
The table name
columns : list
List of sqlalchemy.Column objects
constraints : list, optional
List of sqlalchemy.Constraint objects
Returns
-------
tbl : sqlalchemy.Table object
User may instantiate immediately with sqlalchemy.Table.create
method
"""

tbl = Table(name, self._metadata, *columns)
for c in constraints:
tbl.append_constraint(c)

return tbl

def create_table(self, name, columns, constraints=None):
"""
Define and instantiate a single table.
Parameters
----------
name : str
The table name
columns : list
List of sqlalchemy.Column objects
constraints : list, optional
List of sqlalchemy.Constraint objects
"""

tbl = define_table(self, name, columns, constraints)
tbl.create(self._engine)

def create_all(self):
"""
Instantiate all tables defined so far which don't already exist
"""
self.create_schema()
self._metadata.create_all(self._engine)
try:
self.grant_reader_access("reg_reader")
except:
print("Could not grant access to reg_reader")

def get_table_metadata(self, table_name):
"""
Return metadata for a particular table in the database.
Parameters
----------
table_name : str
Returns
-------
- : Table object
"""

if not "." in table_name:
table_name = ".".join([self._schema, table_name])
return self._metadata.tables[table_name]

def create_schema(self):
"""
Create a new schema in the database (if it doesn't already exist).
Schema name is taken from `self._schema`.
"""

if self._dialect == "sqlite":
return
stmt = f"CREATE SCHEMA IF NOT EXISTS {self._schema}"
with self._engine.connect() as conn:
conn.execute(text(stmt))
conn.commit()

def grant_reader_access(self, acct):
"""
Grant USAGE on schema, SELECT on tables to specified account.
Parameters
----------
acct : str
Name of account we are granting read access to.
"""
if self._dialect == "sqlite":
return
# Cannot figure out how to pass value of acct using parameters,
# so for safety do minimal checking ourselves: check that value of
# acct has no spaces
if len(acct.split()) != 1:
raise ValueException(f"grant_reader_access: {acct} is not a valid account")
usage_priv = f"GRANT USAGE ON SCHEMA {self._schema} to {acct}"
select_priv = f"GRANT SELECT ON ALL TABLES IN SCHEMA {self._schema} to {acct}"
with self._engine.connect() as conn:
conn.execute(text(usage_priv))
conn.execute(text(select_priv))
conn.commit()


class TableMetadata:
def __init__(self, db_connection, get_db_version=True):
"""
Expand Down

0 comments on commit 12f63d7

Please sign in to comment.