def copy_database(
    src_url: str,
    tgt_url: str,
    src_prefix: str,  # = mod_db.DEFAULT_DATABASE_PREFIX,
    tgt_prefix: str,  # = mod_db.DEFAULT_DATABASE_PREFIX
):
    """Copy all data from a source database to an EMPTY target database.

    Important considerations:

    - All source data will be appended to the target tables, so it is
        important that the target database is empty.

    - Will fail if the databases are not at the latest schema revision. That
        can be fixed with `TruSession(database_url="...", database_prefix="...").migrate_database()`

    - Might fail if the target database enforces relationship constraints,
        because then the order of inserting data matters.

    - This process is NOT transactional, so it is highly recommended that
        the databases are NOT used by anyone while this process runs.
    """

    # Avoids circular imports.
    from trulens.core.database.sqlalchemy import SQLAlchemyDB

    src = SQLAlchemyDB.from_db_url(src_url, table_prefix=src_prefix)
    check_db_revision(src.engine, prefix=src_prefix)

    tgt = SQLAlchemyDB.from_db_url(tgt_url, table_prefix=tgt_prefix)
    check_db_revision(tgt.engine, prefix=tgt_prefix)

    print("Source database:")
    print(pformat(src))

    print("Target database:")
    print(pformat(tgt))

    for k, source_table_class in src.orm.registry.items():
        # ["apps", "feedback_defs", "records", "feedbacks"]:

        if not hasattr(source_table_class, "_table_base_name"):
            continue

        target_table_class = tgt.orm.registry.get(k)

        with src.engine.begin() as src_conn:
            with tgt.engine.begin() as tgt_conn:
                df = pd.read_sql(
                    f"SELECT * FROM {source_table_class.__tablename__}",
                    src_conn,
                )
                df.to_sql(
                    target_table_class.__tablename__,
                    tgt_conn,
                    index=False,
                    if_exists="append",
                )

                print(
                    f"Copied {len(df)} rows from {source_table_class.__tablename__} in source {target_table_class.__tablename__} in target."
                )
Copy all data from a source database to an EMPTY target database.

    Important considerations:

    - All source data will be appended to the target tables, so it is
        important that the target database is empty.

    - Will fail if the databases are not at the latest schema revision. That
        can be fixed with `TruSession(database_url="...", database_prefix="...").migrate_database()`

    - Might fail if the target database enforces relationship constraints,
        because then the order of inserting data matters.

    - This process is NOT transactional, so it is highly recommended that
        the databases are NOT used by anyone while this process runs.
    
src/core/trulens/core/database/utils.py