Пример #1
0
def load_experiment_by_name(
        name: str,
        sample: Optional[str] = None,
        conn: Optional[ConnectionPlus] = None) -> Experiment:
    """
    Try to load experiment with the specified name.

    Nothing stops you from having many experiments with the same name and
    sample_name. In that case this won't work. And warn you.

    Args:
        name: the name of the experiment
        sample: the name of the sample
        conn: connection to the database. If not supplied, a new connection
          to the DB file specified in the config is made

    Returns:
        the requested experiment

    Raises:
        ValueError if the name is not unique and sample name is None.
    """
    conn = conn or connect(get_DB_location())

    if sample:
        sql = """
        SELECT
            *
        FROM
            experiments
        WHERE
            sample_name = ? AND
            name = ?
        """
        c = transaction(conn, sql, sample, name)
    else:
        sql = """
        SELECT
            *
        FROM
            experiments
        WHERE
            name = ?
        """
        c = transaction(conn, sql, name)
    rows = c.fetchall()
    if len(rows) == 0:
        raise ValueError("Experiment not found")
    elif len(rows) > 1:
        _repr = []
        for row in rows:
            s = (f"exp_id:{row['exp_id']} ({row['name']}-{row['sample_name']})"
                 f" started at ({row['start_time']})")
            _repr.append(s)
        _repr_str = "\n".join(_repr)
        raise ValueError(f"Many experiments matching your request"
                         f" found:\n{_repr_str}")
    else:
        e = Experiment(exp_id=rows[0]['exp_id'], conn=conn)
    return e
Пример #2
0
def test_atomic_raises(experiment):
    conn = experiment.conn

    bad_sql = '""'

    # it seems that the type of error raised differs between python versions
    # 3.6.0 (OperationalError) and 3.6.3 (RuntimeError)
    # -strange, huh?
    with pytest.raises((OperationalError, RuntimeError)):
        with mut.atomic(conn):
            mut.transaction(conn, bad_sql)
Пример #3
0
def load_experiment_by_name(name: str,
                            sample: Optional[str] = None) -> Experiment:
    """
    Try to load experiment with the specified name.
    Nothing stops you from having many experiments with
    the same name and sample_name.
    In that case this won't work. And warn you.
    Args:
        name: the name of the experiment
        sample: the name of the sample

    Returns:
        the requested experiment

    Raises:
        ValueError if the name is not unique and sample name is None.
    """
    e = Experiment(get_DB_location())
    if sample:
        sql = """
        SELECT
            *
        FROM
            experiments
        WHERE
            sample_name = ? AND
            name = ?
        """
        c = transaction(e.conn, sql, sample, name)
    else:
        sql = """
        SELECT
            *
        FROM
            experiments
        WHERE
            name = ?
        """
        c = transaction(e.conn, sql, name)
    rows = c.fetchall()
    if len(rows) == 0:
        raise ValueError("Experiment not found \n")
    elif len(rows) > 1:
        _repr = []
        for row in rows:
            s = f"exp_id:{row['exp_id']} ({row['name']}-{row['sample_name']}) started at({row['start_time']})"
            _repr.append(s)
        _repr_str = "\n".join(_repr)
        raise ValueError(
            f"Many experiments matching your request found {_repr_str}")
    else:
        e.exp_id = rows[0]['exp_id']
    return e
Пример #4
0
def test_atomic_creation(experiment):
    """"
    Test that dataset creation is atomic. Test for
    https://github.com/QCoDeS/Qcodes/issues/1444
    """
    def just_throw(*args):
        raise RuntimeError("This breaks adding metadata")

    # first we patch add_meta_data to throw an exception
    # if create_data is not atomic this would create a partial
    # run in the db. Causing the next create_run to fail
    with patch('qcodes.dataset.sqlite_base.add_meta_data', new=just_throw):
        x = ParamSpec('x', 'numeric')
        t = ParamSpec('t', 'numeric')
        y = ParamSpec('y', 'numeric', depends_on=['x', 't'])
        with pytest.raises(
                RuntimeError,
                match="Rolling back due to unhandled exception") as e:
            mut.create_run(experiment.conn,
                           experiment.exp_id,
                           name='testrun',
                           guid=generate_guid(),
                           parameters=[x, t, y],
                           metadata={'a': 1})
    assert error_caused_by(e, "This breaks adding metadata")
    # since we are starting from an empty database and the above transaction
    # should be rolled back there should be no runs in the run table
    runs = mut.transaction(experiment.conn,
                           'SELECT run_id FROM runs').fetchall()
    assert len(runs) == 0
    with shadow_conn(experiment.path_to_db) as new_conn:
        runs = mut.transaction(new_conn, 'SELECT run_id FROM runs').fetchall()
        assert len(runs) == 0

    # if the above was not correctly rolled back we
    # expect the next creation of a run to fail
    mut.create_run(experiment.conn,
                   experiment.exp_id,
                   name='testrun',
                   guid=generate_guid(),
                   parameters=[x, t, y],
                   metadata={'a': 1})

    runs = mut.transaction(experiment.conn,
                           'SELECT run_id FROM runs').fetchall()
    assert len(runs) == 1

    with shadow_conn(experiment.path_to_db) as new_conn:
        runs = mut.transaction(new_conn, 'SELECT run_id FROM runs').fetchall()
        assert len(runs) == 1
Пример #5
0
def load_by_counter(counter, exp_id):
    """
    Load a dataset given its counter in one experiment
    Args:
        counter: Counter of the dataset
        exp_id:  Experiment the dataset belongs to

    Returns:
        the dataset
    """
    conn = connect(get_DB_location())
    sql = """
    SELECT run_id
    FROM
      runs
    WHERE
      result_counter= ? AND
      exp_id = ?
    """
    c = transaction(conn, sql, counter, exp_id)
    run_id = one(c, 'run_id')
    conn.close()
    d = DataSet(get_DB_location(), run_id=run_id)

    return d
Пример #6
0
def load_by_counter(counter: int,
                    exp_id: int,
                    conn: Optional[ConnectionPlus] = None) -> DataSet:
    """
    Load a dataset given its counter in a given experiment

    Lookup is performed in the database file that is specified in the config.

    Args:
        counter: counter of the dataset within the given experiment
        exp_id: id of the experiment where to look for the dataset
        conn: connection to the database to load from. If not provided, a
          connection to the DB file specified in the config is made

    Returns:
        dataset of the given counter in the given experiment
    """
    conn = conn or connect(get_DB_location())
    sql = """
    SELECT run_id
    FROM
      runs
    WHERE
      result_counter= ? AND
      exp_id = ?
    """
    c = transaction(conn, sql, counter, exp_id)
    run_id = one(c, 'run_id')

    d = DataSet(conn=conn, run_id=run_id)
    return d
Пример #7
0
def get_run_timestamp(run_id):
    DB = qc.config["core"]["db_location"]

    d = DataSet(DB)
    sql = """
    SELECT run_timestamp
    FROM
      runs
    WHERE
      run_id= ?
    """
    c = transaction(d.conn, sql, run_id)
    run_timestamp = one(c, 'run_timestamp')
    return run_timestamp
Пример #8
0
def load_by_counter(counter, exp_id):
    """
    Load a dataset given its counter in one experiment
    Args:
        counter: Counter of the dataset
        exp_id:  Experiment the dataset belongs to

    Returns:
        the dataset
    """
    d = DataSet(DB)
    sql = """
    SELECT run_id
    FROM
      runs
    WHERE
      result_counter= ? AND
      exp_id = ?
    """
    c = transaction(d.conn, sql, counter, exp_id)
    d.run_id = one(c, 'run_id')
    return d
Пример #9
0
 def _remove_trigger(self, name):
     transaction(self.conn, f"DROP TRIGGER IF EXISTS {name};")