예제 #1
0
def mongodb_to_topic_store(scenario_file, topic_store_file):
    client = MongoStorage.load(scenario_file)
    print("Converting MongoDB '{}' to '{}'".format(client.uri, topic_store_file.name))

    storage = get_mongo_storage_by_session(client)
    count = storage.cursor.count()

    topic_storage = TopicStorage(topic_store_file)

    with tqdm(total=count) as progress_bar:
        for item in storage:
            topic_storage.insert_one(item)
            progress_bar.update()
예제 #2
0
def topic_store_to_mongodb(topic_store_file, scenario_file):
    client = MongoStorage.load(scenario_file)
    print("Converting '{}' to MongoDB '{}'".format(topic_store_file.name, client.uri))

    storage = TopicStorage.load(topic_store_file)
    count = len(storage)  # TODO: very slow operation
    with tqdm(total=count) as progress_bar:
        for item in storage:
            try:
                client.insert_one(item)
            except pymongo.errors.DuplicateKeyError:
                print("Storage Item '_id: {}' already exists in the '{}/{}' collection".format(item.id, client.name,
                                                                                               client.collection_name))
            progress_bar.update()
예제 #3
0
def _convert_cli():
    parser = argparse.ArgumentParser()
    parser.add_argument("-i",
                        "--input",
                        help="Input File",
                        type=str,
                        required=True)
    parser.add_argument("-o",
                        "--output",
                        help="Output File",
                        type=str,
                        required=True)
    parser.add_argument(
        "-c",
        "--collection",
        help="MongoDB collection to use if URI passed as --input",
        type=str,
        required=False)
    parser.add_argument("-q",
                        "--query",
                        help='MongoDB input query as dict (example: -q '
                        '\'{"_id": "ObjectId(5f718a354e5e8239dcd1eca1)"}\'',
                        type=str,
                        required=False,
                        default=None)
    parser.add_argument(
        "-p",
        "--projection",
        help='MongoDB input projection as dict (example: -p \'{"name": 1}\'',
        type=str,
        required=False,
        default=None)
    args = parser.parse_args()

    rospy.init_node("topic_store_convert", anonymous=True)
    input_path = pathlib.Path(args.input)
    output_path = pathlib.Path(args.output)

    # if not input_path.exists():
    #     raise IOError("Input file '{}' does not exist".format(input_path))

    if input_path.suffix == ".bag":
        raise NotImplementedError(
            "Converting from ROS bags is not currently supported. "
            "The conversion to ROS bags is lossy and requires adding meta data to reconstruct"
            "the original .topic_store or database documents")
    elif input_path.suffix == TopicStorage.suffix and output_path.suffix == ".bag":
        topic_store_to_ros_bag(input_path, output_path)
    elif input_path.suffix == ".yaml" and output_path.suffix == TopicStorage.suffix:
        input_path = resolve_scenario_yaml(input_path)
        mongodb_to_topic_store(MongoStorage.load(input_path), output_path)
    elif input_path.suffix == ".yaml" and output_path.suffix == ".bag":
        input_path = resolve_scenario_yaml(input_path)
        mongodb_to_ros_bag(MongoStorage.load(input_path), output_path)
    elif input_path.suffix == TopicStorage.suffix and output_path.suffix == ".yaml":
        output_path = resolve_scenario_yaml(output_path)
        topic_store_to_mongodb(input_path, output_path)
    elif is_uri(args.input):
        srv = args.input
        collection = args.collection
        query = args.query
        projection = args.projection

        # if not hasattr(args, "query") or not args.query:
        #     raise ValueError("If input is a MongoDB URI you must specify a DB query -q/--query to export data")
        if not hasattr(args, "collection") or not args.collection:
            raise ValueError(
                "If input is a MongoDB URI you must specify a DB collection -c/--collection to query data"
            )

        # Try to parse a query/projection string to a dict and perform some basic cleaning
        # The query string will filter the db documents by client.find(query)
        if query is not None:
            try:
                query, projection = [
                    x if x is None else json.loads(x)
                    for x in [args.query, args.projection]
                ]
            except ValueError:
                print(
                    "Query/Projection parameter cannot be parsed as a python dict \nQ: '{}'\nP: '{}'"
                    .format(args.query, args.projection))
                raise

        # Some simple rules to support searching by ID from console
        if query:
            for k, v in query.items():
                try:
                    unicode
                except NameError:
                    unicode = str
                if isinstance(v, (str, unicode)) and (v.startswith('ObjectId(')
                                                      and v.endswith(')')):
                    print("Converting query field '{}' to ObjectId".format(k))
                    query[k] = ObjectId(str(v[9:-1]))

        client = client_from_uri(srv, collection=collection)

        if is_uri(args.output):
            db2 = client_from_uri(args.output, collection=collection)
            mongodb_to_mongodb(client, db2, query=query, projection=projection)
        elif output_path.suffix == ".bag":
            mongodb_to_ros_bag(client,
                               output_path,
                               query=query,
                               projection=projection)
        elif output_path.suffix == TopicStorage.suffix:
            mongodb_to_topic_store(client,
                                   output_path,
                                   query=query,
                                   projection=projection)
        else:
            raise ValueError(
                "No valid conversion from Mongo URI '{}' to '{}' file".format(
                    client.uri, output_path))
    elif input_path.suffix == output_path.suffix:
        print("No conversion or migration for '{}' to '{}'".format(
            input_path, output_path))
        print(
            "If you would like to copy the file please use 'cp {} {}'".format(
                input_path, output_path))
    else:
        print("No conversion or migration for '{}' to '{}'".format(
            input_path, output_path))