skills/oleander-iceberg-catalog/SKILL.md
Patterns for reading and writing oleander Iceberg catalog tables in Spark jobs, including naming conventions, write modes, and catalog hierarchy.
npx skillsauth add kilo-org/kilo-marketplace oleander-iceberg-catalogInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this skill when reading from or writing to the oleander Iceberg catalog in a Spark job.
Tables are addressed as catalog.namespace.table:
oleander for the managed Lakekeeper-backed catalogdefault, san_francisco, my_org)By default, default and telemetry namespaces are available out of the box. The telemetry namespace contains oleander-managed data you can query directly (for example oleander.telemetry.run_events, oleander.telemetry.traces, and oleander.telemetry.logs).
Examples:
oleander.default.sf_311
oleander.san_francisco.district_stats
oleander.my_namespace.results
Use spark.table() with the fully qualified name:
df = spark.table("oleander.default.sf_311")
Never construct table paths as raw S3 URIs. Always use the catalog name so Iceberg metadata and lineage are tracked correctly.
Append (add rows to an existing or new table):
df.writeTo("oleander.my_namespace.my_table").append()
Overwrite (replace table contents):
df.write.mode("overwrite").saveAsTable("oleander.my_namespace.my_table")
Use writeTo(...).append() for incremental pipelines. Use write.mode("overwrite").saveAsTable(...) when replacing full result sets each run.
Avoid collecting data to the driver and then writing from Python memory. Keep writes as Spark DataFrame operations so Iceberg handles the transaction, partitioning, and metadata correctly.
Bad:
rows = df.collect()
# write rows from Python memory
Good:
df.write.mode("overwrite").saveAsTable("oleander.my_namespace.my_table")
Accept table names as arguments or environment variables so scripts are reusable:
import os, argparse
parser = argparse.ArgumentParser()
parser.add_argument("--input-table", default="oleander.default.sf_311")
parser.add_argument("--output-catalog", default="oleander.my_namespace")
args = parser.parse_args()
df = spark.table(args.input_table)
df.write.mode("overwrite").saveAsTable(f"{args.output_catalog}.results")
If a table is read and used in multiple downstream transforms, cache it once and unpersist when done:
df = spark.table("oleander.default.sf_311")
df.cache()
# ... multiple transforms ...
df.unpersist()
Do not cache tables that are only used once.
development
Oracle Database guidance for SQL, PL/SQL, SQLcl, ORDS, administration, app development, performance, security, migrations, and agent-safe database workflows. Use when the user asks to write, edit, rewrite, review, format, debug, tune, or explain SQL; create or refactor PL/SQL; use SQLcl, Liquibase, ORDS, JDBC, node-oracledb, Python, Java, .NET, or database frameworks; troubleshoot queries, sessions, locks, waits, indexes, optimizer plans, AWR, ASH, migrations, schemas, users, roles, privileges, backup, recovery, Data Guard, RAC, multitenant, containers, monitoring, auditing, encryption, VPD, or safe agent database operations.
data-ai
Integrate Okta for enterprise identity workflows including OIDC login, group claims, and policy-based access controls. Use when implementing workforce or B2B identity scenarios.
documentation
Use when arranging Apache NiFi processors, process groups, ports, comments, numbering, crossing connections, dense fan-in/fan-out, or reusable readable canvas layouts.
tools
This subskill should be used when composing or running ad hoc NRQL queries for New Relic telemetry, facets, time windows, rates, and comparisons. Use newrelic-nrql-debug-ladder instead for failing, empty, or schema-mismatched queries.