예제 #1
0
def infer_table_column_types(schema, table_name, engine):
    table = reflect_table(table_name, schema, engine)

    temp_name = TEMP_TABLE % (int(time()))
    schemas.create_schema(TEMP_SCHEMA, engine)
    with engine.begin() as conn:
        while engine.dialect.has_table(conn, temp_name, schema=TEMP_SCHEMA):
            temp_name = TEMP_TABLE.format(int(time()))

    full_temp_name = f"{TEMP_SCHEMA}.{temp_name}"

    select_table = select(table)
    with engine.begin() as conn:
        conn.execute(CreateTableAs(full_temp_name, select_table))
    temp_table = reflect_table(temp_name, TEMP_SCHEMA, engine)

    try:
        update_table_column_types(
            TEMP_SCHEMA, temp_table.name, engine,
        )
    except Exception as e:
        # Ensure the temp table is deleted
        temp_table.drop()
        raise e
    else:
        temp_table = reflect_table(temp_name, TEMP_SCHEMA, engine)
        types = [c.type.__class__ for c in temp_table.columns]
        temp_table.drop()
        return types
예제 #2
0
def test_delete_schema(engine, if_exists):
    test_schema = "test_delete_schema"

    schemas.create_schema(test_schema, engine)
    current_schemas = schemas.get_mathesar_schemas(engine)
    assert test_schema in current_schemas

    schemas.delete_schema(test_schema, engine, if_exists=if_exists)
    current_schemas = schemas.get_mathesar_schemas(engine)
    assert test_schema not in current_schemas
예제 #3
0
def test_rename_schema(engine):
    test_schema = "test_rename_schema"
    new_test_schema = "test_rename_schema_new"

    schemas.create_schema(test_schema, engine)
    current_schemas = schemas.get_mathesar_schemas(engine)
    assert test_schema in current_schemas

    schemas.rename_schema(test_schema, engine, new_test_schema)
    current_schemas = schemas.get_mathesar_schemas(engine)
    assert test_schema not in current_schemas
    assert new_test_schema in current_schemas
예제 #4
0
def test_delete_schema_restricted(engine):
    test_schema = "test_delete_schema_restricted"
    test_table = "test_delete_schema_restricted_table"

    schemas.create_schema(test_schema, engine)
    tables.create_mathesar_table(test_table, test_schema, [], engine)

    with pytest.raises(DependentObjectsStillExist):
        schemas.delete_schema(test_schema, engine)

    current_schemas = schemas.get_mathesar_schemas(engine)
    assert test_schema in current_schemas
예제 #5
0
def test_delete_schema_cascade(engine):
    test_schema = "test_delete_schema_cascade"
    test_table = "test_delete_schema_cascade_table"

    schemas.create_schema(test_schema, engine)
    table = tables.create_mathesar_table(test_table, test_schema, [], engine)

    schemas.delete_schema(test_schema, engine, cascade=True)

    current_schemas = schemas.get_mathesar_schemas(engine)
    assert test_schema not in current_schemas
    with pytest.raises(NoSuchTableError):
        tables.reflect_table(table.name, test_schema, engine)
예제 #6
0
def create_schema_and_object(name, database):
    engine = create_mathesar_engine(database)

    all_schemas = get_mathesar_schemas(engine)
    if name in all_schemas:
        raise ValidationError({"name": f"Schema name {name} is not unique"})

    try:
        database_model = Database.objects.get(name=database)
    except ObjectDoesNotExist:
        raise ValidationError({"database": f"Database '{database}' not found"})

    create_schema(name, engine)
    schema_oid = get_schema_oid_from_name(name, engine)

    schema = Schema.objects.create(oid=schema_oid, database=database_model)
    return schema
예제 #7
0
def _create_related_table(schema, related_schema, table, related_table,
                          engine):
    schemas.create_schema(schema, engine)
    table = tables.create_mathesar_table(table, schema, [], engine)

    schemas.create_schema(related_schema, engine)
    metadata = MetaData(schema=related_schema, bind=engine)
    related_table = Table(
        related_table, metadata,
        Column('id', Integer, ForeignKey(table.c[constants.ID])))
    related_table.create()

    related_table = tables.reflect_table(related_table.name, related_schema,
                                         engine)
    fk = list(related_table.foreign_keys)[0]
    assert fk.column.table.schema == schema

    return related_table
예제 #8
0
def test_multi_db_schema(engine, multi_db_engine, client):
    test_schemas = ["test_schema_1", "test_schema_2"]
    for schema in test_schemas:
        schemas.create_schema(schema, engine)
        schemas.create_schema("multi_db_" + schema, multi_db_engine)

    cache.clear()
    response = client.get('/api/v0/schemas/')
    response_data = response.json()
    response_schemas = [
        s['name'] for s in response_data['results'] if s['name'] != 'public'
    ]

    assert response.status_code == 200
    assert len(response_schemas) == 4

    expected_schemas = test_schemas + ["multi_db_" + s for s in test_schemas]
    assert set(response_schemas) == set(expected_schemas)

    # We have to delete the schemas to not break later tests
    with engine.begin() as conn:
        for schema in test_schemas:
            conn.execute(DropSchema(schema))
예제 #9
0
def create_mathesar_table(name, schema, columns_, engine, metadata=None):
    """
    This method creates a Postgres table in the specified schema using the
    given name and column list.  It adds internal mathesar columns to the
    table.
    """
    columns_ = columns.init_mathesar_table_column_list_with_defaults(columns_)
    schemas.create_schema(schema, engine)
    # We need this so that we can create multiple mathesar tables in the
    # same MetaData, enabling them to reference each other in the
    # SQLAlchemy context (e.g., for creating a ForeignKey relationship)
    if metadata is None:
        metadata = MetaData(bind=engine, schema=schema)
    # This reflection step lets us notice any "table already exists"
    # errors before sending error-generating requests to the DB.
    metadata.reflect()
    table = Table(
        name,
        metadata,
        *columns_,
        schema=schema
    )
    table.create(engine)
    return table
예제 #10
0
def create_type_schema(engine):
    create_schema(base.SCHEMA, engine)
예제 #11
0
def schema(engine, test_db_model):
    create_schema(TEST_SCHEMA, engine)
    schema_oid = get_schema_oid_from_name(TEST_SCHEMA, engine)
    yield Schema.objects.create(oid=schema_oid, database=test_db_model)
    with engine.begin() as conn:
        conn.execute(text(f'DROP SCHEMA "{TEST_SCHEMA}" CASCADE;'))