def get_db_state(): """Inspect the database, and return a representation of its contents The return value is a dictionary mapping table names to dictionaries containing two keys each: - 'schema', which describes the columns for that table. - 'rows', which is a list of all rows in the table. """ result = {} inspector = db.inspect(db.engine) metadata = db.MetaData() for name in inspector.get_table_names(): schema = inspector.get_columns(name) tbl = db.Table(name, metadata) inspector.reflecttable(tbl, None) rows = db.session.query(tbl).all() # the inspector gives us the schema as a list, and the rows # as a list of tuples. the columns in each row are matched # up with the schema by position, but this may vary # (acceptably) depending on when migration scripts are run. # So, we normalize this by converting both to dictionaries # with the column names as keys. row_dicts = [] for row in rows: row_dicts.append({}) for i in range(len(row)): row_dicts[-1][schema[i]['name']] = row[i] schema = dict((col['name'], col) for col in schema) result[name] = { 'schema': schema, 'rows': sorted(row_dicts), } return result
self.is_admin = is_admin self.set_password(password) def verify_password(self, password): """Return whether `password` is the user's (plaintext) password.""" return sha512_crypt.verify(password, self.hashed_password) def set_password(self, password): """Set the user's password to `password` (which must be plaintext).""" self.hashed_password = sha512_crypt.encrypt(password) # A joining table for users and projects, which have a many to many # relationship: user_projects = db.Table('user_projects', db.Column('user_id', db.ForeignKey('user.id')), db.Column('project_id', db.ForeignKey('project.id'))) @rest_call('PUT', '/auth/basic/user/<user>', schema=Schema({ 'user': basestring, 'password': basestring, Optional('is_admin'): bool, }), dont_log=('password', )) def user_create(user, password, is_admin=False): """Create user with given password. If the user already exists, a DuplicateError will be raised.
# It is important that the entry for HIL core ('hil') is first; I(zenhack) # assume this has something to do with search order, but this hangs # otherwise. paths_scratch = paths.copy() core_path = paths_scratch.pop('hil') configval = ' '.join([core_path] + list(paths_scratch.values())) config.set_main_option('version_locations', configval) return config # Alembic will create this table itself if need be when doing "stamp" in the # create_db function below, but unless we declare it, db.drop_all() won't # know about it, and will leave us with a one-table database. AlembicVersion = db.Table( 'alembic_version', db.metadata, db.Column('version_num', db.String(32), nullable=False)) def _expected_heads(): cfg_path = join(dirname(__file__), 'migrations', 'alembic.ini') cfg = Config(cfg_path) _configure_alembic(cfg) cfg.set_main_option('script_location', dirname(cfg_path)) script_dir = ScriptDirectory.from_config(cfg) return set(script_dir.get_heads()) def create_db(): """Create and populate the initial database.