Článek přečtěte do 7 min.

S tím, jak se databáze vyvíjejí, aby byly autonomnější a vstřícnější ke cloudu, potřebují vývojáři efektivní a spolehlivé metody, jak se s nimi spojit a pracovat s nimi. Tento příspěvek poskytne přehled o tom, jak se připojit a dotazovat autonomní databázi Oracle (ADB) z některých oblíbených programovacích jazyků, a některé rozdíly v každé implementaci.

Předpoklady

Než se ponoříte do databázových připojení z konkrétních jazyků, samozřejmě potřebujete mít jazykovou podporu pro každou dostupnou vazbu databáze Oracle. Obvykle to znamená mít na vašem systému nainstalovaný jazyk a související nástroje (překladač/překladač, správce balíčků atd.). Pro některá připojení ovladačů budete potřebovat také knihovny Oracle, které jsou součástí instalací Oracle DB nebo je lze získat prostřednictvím Oracle Instant Client.

Oracle Instant Client umožňuje vývoj a nasazení aplikací, které se připojují k databázi Oracle, buď on-premise, nebo v cloudu. Knihovny Instant Client poskytují nezbytné síťové připojení a pokročilé datové funkce pro plné využití databáze Oracle. Knihovny jsou používány rozhraními Oracle API populárních jazyků a prostředí, včetně Pythonu, Node.js, Go, PHP a Ruby, a také poskytují přístup pro Oracle Call Interface (OCI), Oracle C++ Call Interface (OCCI), JDBC OCI, Aplikace ODBC a Pro*C.

Jazykové vazby pro Oracle často spoléhají na knihovny Oracle Instant Client, aby usnadnily připojení k databázím Oracle, včetně ADB, buď prostřednictvím rozhraní Oracle Call Interface (OCI) nebo Oracle Database Programming Interface for C (ODPI-C) (více o nich níže).

Poznámka: Pokud jste vývojář pro Mac, v době psaní tohoto článku neexistuje žádná nativní verze knihoven Oracle Instant Client pro Macbooky Apple založené na křemíku (na bázi ARM M1/M2). Vývojáři s tímto typem strojů budou muset k překlenutí této mezery použít Rosetta 2 (dokud nebudou vydány knihovny založené na ARM).

Široká škála databázových vazeb Oracle

Jakmile nastavíte svou autonomní databázi na Oracle Cloud Infrastructure (OCI), dalším krokem je vytvoření připojení z vaší aplikace. Krajina ovladačů a vázání dostupných pro tento účel je tak rozmanitá, jako je robustní:

Vazby databázového jazyka Oracle
Vazby databázového jazyka Oracle

Řada možností sahá od iniciativ s otevřeným zdrojovým kódem až po ovladače podporované Oracle. Tyto různé konektory nabízejí jedinečné výhody a vyhovují různým scénářům. Některá jsou komunitou řízená a odrážejí inovaci a ducha spolupráce open-source kultury. Jiné přicházejí s podporou a podporou Oracle, zajišťující kompatibilitu a často komplexní dokumentaci.

Zásadním rozdílem mezi těmito vázáními je rozdělení mezi „Thin“ a „Thick“ ovladači. Tenké ovladače jsou navrženy pro efektivní provoz; vytvářejí konektivitu bez potřeby klientských knihoven Oracle, což usnadňuje jednoduché a agilní nastavení. To může být výhodné zejména při snaze minimalizovat nároky na aplikaci nebo při práci v prostředích, kde je nasazení knihoven specifických pro Oracle nepraktické.

Naproti tomu ovladače, které vyžadují knihovny Oracle (Thick Drivers), využívají hlubší úroveň funkčnosti Oracle a využívají OCI nebo ODPI-C pro své vrstvy připojení. Každá z těchto vrstev představuje svou vlastní složitost a schopnosti:

  • OCI (Oracle Call Interface) : Toto je tradiční a na funkce bohaté API, které umožňuje jemnou kontrolu nad interakcemi s databází. Často je to volba pro aplikace, které potřebují využívat celé spektrum funkcí Oracle a kde je výkon zásadním problémem.
  • ODPI-C (Oracle Database Programming Interface for C): ODPI-C, který funguje jako vysokoúrovňová abstrakce přes OCI, nabízí jednodušší a efektivnější API, které stále poskytuje komplexní funkce Oracle, ale se sníženou složitostí. Je vhodný pro aplikace, které vyžadují rovnováhu mezi snadností použití pro vývojáře a přístupem k pokročilým funkcím databáze.

Dvě vazby Rust: rust-oracle a Sibyla

Pro vývojáře Rust rust-oracleSibyljsou to dvě prominentní open source „tlusté“ vazby ovladačů. Oba závisí na výše zmíněných knihovnách Oracle, přičemž rust-oraclejsou založeny na OCI a Sibylvyužívají ODPI-C. Obě poskytují robustní prostředky pro připojení k ADB, ale liší se většinou z hlediska složitosti implementace a sady funkcí (například knihovna Sibyl obsahuje nativní podporu pro asynchronní volání).

Podívejme se na základní úryvky kódu pro připojení a předání dotazu k načtení verze serveru v rust-oracle :

// Rust code using rust-oracle to connect to ADB and execute a SQL query<font></font>
use oracle::{Connection, Error, RowValue};<font></font>
<font></font>
fn main() -> Result<(), Error> {<font></font>
    // Set the TNS_ADMIN environment variable<font></font>
    env::set_var("TNS_ADMIN", "/path/to/your/wallet_directory");<font></font>
<font></font>
    let conn = Connection::connect("user", "password", "//adb.instance.url")?;<font></font>
    println!("Connected to database successfully.");<font></font>
<font></font>
    let sql = "SELECT * FROM v$version WHERE banner LIKE 'Oracle%'";<font></font>
    let rows = conn.query(sql, &[])?;<font></font>
<font></font>
    for row_result in rows {<font></font>
        let row: RowValue = row_result?;<font></font>
        let version: String = row.get("banner")?;<font></font>
        println!("Oracle DB Version: {}", version);<font></font>
    }<font></font>
    Ok(())<font></font>
}

A nyní v podstatě stejný kód se Sibylou:

// Rust code using Sibyl to connect to ADB and execute a SQL query<font></font>
use sibyl::{Cursor, Error, Session};<font></font>
<font></font>
fn main() -> Result<(), Error> {<font></font>
    // Set the TNS_ADMIN environment variable<font></font>
    env::set_var("TNS_ADMIN", "/path/to/your/wallet_directory");<font></font>
<font></font>
    let session = Session::new("user", "password", "//adb.instance.url")?;<font></font>
    println!("Connected to database successfully.");<font></font>
<font></font>
    let sql = "SELECT * FROM v$version WHERE banner LIKE 'Oracle%'";<font></font>
    let mut cursor = session.prepare(sql)?.query(())?;<font></font>
<font></font>
    while let Some(row) = cursor.next_row()? {<font></font>
        let version: String = row.get(0)?;<font></font>
        println!("Oracle DB Version: {}", version);<font></font>
    }<font></font>
<font></font>
    Ok(())<font></font>
}

Jak můžete vidět, kód je v obou knihovnách velmi podobný a některé rozdíly jsou patrnější, když se pustíte do pokročilejšího kódu, jako je zpracování DML, podpora async atd.

Aby tyto úryvky fungovaly, musí být knihovny Oracle viditelné z cesty dynamické knihovny ve vašem OS. A pamatujte, že pokud používáte křemík Apple, budete potřebovat Rosetta 2, jak již bylo zmíněno, a sestavení, které cílí na Intel:

cargo build --target x86_64-apple-darwin

Poznámka:

Pokud chcete vidět tyto dvě knihovny v akci, nenechte si ujít tento nahraný webinář:

Máme také další dva skvělé blogové příspěvky týkající se každého z těchto vazeb, které stojí za to vyzkoušet:

One Go vázání: godror

Pro vývojáře Go godror je komplexní balíček postavený na víceúrovňové architektuře (Go, CGO, ODPI-C (a pak OCI)).

Zde je podobné připojení fragmentu kódu k ADB a předání dotazu:

// Go code using godror to connect to ADB and execute a SQL query<font></font>
package main<font></font>
<font></font>
import (<font></font>
    "database/sql"<font></font>
    "fmt"<font></font>
    _ "github.com/godror/godror"<font></font>
)<font></font>
<font></font>
func main() {<font></font>
    // Set the path to the directory containing your Oracle wallet<font></font>
    os.Setenv("TNS_ADMIN", "/path/to/your/wallet_directory")<font></font>
<font></font>
    db, err := sql.Open("godror", "user/password@adb.instance.url")<font></font>
    if err != nil {<font></font>
        fmt.Println("Error connecting to the database: ", err)<font></font>
        return<font></font>
    }<font></font>
    defer db.Close()<font></font>
<font></font>
    rows, err := db.Query("SELECT * FROM v$version WHERE banner LIKE 'Oracle%'")<font></font>
    if err != nil {<font></font>
        fmt.Println("Error performing query: ", err)<font></font>
        return<font></font>
    }<font></font>
    defer rows.Close()<font></font>
<font></font>
    for rows.Next() {<font></font>
        var version string<font></font>
        if err := rows.Scan(&version); err != nil {<font></font>
            fmt.Println("Error reading rows: ", err)<font></font>
            return<font></font>
        }<font></font>
        fmt.Println("Oracle DB Version: ", version)<font></font>
    }<font></font>
}

Ačkoli je knihovna výkonná, podle některých testů může vrstva CGO představovat značnou režii, takže možná budete chtít pečlivě otestovat výkon vaší aplikace založené na godroru s podporou ADB.

Poznámka: Pěkný blogový příspěvek o godroru je „ Připojení k databázím Oracle pomocí Godror a Sqlx “

Jeden „tenký“ ovladač: node-oracledb

Vazba node -oracledb je ovladač s otevřeným zdrojovým kódem podporovaný společností Oracle. Funguje v režimu „tlustý“ i „tenký“ (ve výchozím nastavení „tenký“). „Tenká“ implementace nezávisí na výše zmíněných knihovnách Oracle a obecně se snáze nastavuje. Podívejme se na podobný fragment kódu pro připojení k ADB a předání dotazu:

// Node.js code using node-oracledb "thin" driver to connect to ADB and execute a SQL query<font></font>
const oracledb = require('oracledb');<font></font>
<font></font>
// Set the path to the directory containing your Oracle wallet<font></font>
process.env.TNS_ADMIN = '/path/to/your/wallet_directory';<font></font>
<font></font>
async function run() {<font></font>
    let connection;<font></font>
    try {<font></font>
        connection = await oracledb.getConnection({<font></font>
            user: "user",<font></font>
            password: "password",<font></font>
            connectionString: "adb.instance.url"<font></font>
        });<font></font>
        console.log("Connected to database successfully.");<font></font>
<font></font>
        const result = await connection.execute(<font></font>
            "SELECT * FROM v$version WHERE banner LIKE 'Oracle%'"<font></font>
        );<font></font>
        console.log("Oracle DB Version: ", result.rows);<font></font>
    } catch (err) {<font></font>
        console.error(err);<font></font>
    } finally {<font></font>
        if (connection) {<font></font>
            try {<font></font>
                await connection.close();<font></font>
            } catch (err) {<font></font>
                console.error(err);<font></font>
            }<font></font>
        }<font></font>
    }<font></font>
}<font></font>
<font></font>
run();

Jak můžete vidět výše, na úrovni kódu neexistují žádné rozdíly pro použití režimu „tenký“ nebo „tlustý“. Rozdíl je na úrovni konfigurace, kde v podstatě musíte povolit režim „tlustý“ a poskytnout cestu ke knihovnám Oracle:

const oracledb = require('oracledb');<font></font>
<font></font>
let clientOpts = {};<font></font>
if (process.platform === 'win32') {<font></font>
  // Windows<font></font>
  // If you use backslashes in the libDir string, you will<font></font>
  // need to double them.<font></font>
  clientOpts = { libDir: 'C:\\oracle\\instantclient_19_19' };<font></font>
} else if (process.platform === 'darwin' && process.arch === 'x64') {<font></font>
  // macOS Intel<font></font>
  clientOpts = { libDir: process.env.HOME + '/Downloads/instantclient_19_8' };<font></font>
}<font></font>
// else on other platforms like Linux the system library search path MUST always be<font></font>
// set before Node.js is started, for example with ldconfig or LD_LIBRARY_PATH.<font></font>
<font></font>
// enable node-oracledb Thick mode<font></font>
oracledb.initOracleClient(clientOpts);

Všimněte si, že ve výchozím nastavení knihovna běží v tenkém režimu, takže nepotřebujeme žádné místní knihovny pro usnadnění připojení (protože protokol připojení je implementován v samotném ovladači).

Další „tenký“ ovladač: python-oracledb (dříve cx_Oracle)

Situace je stejná pro Python a knihovnu python-oracledb : ve výchozím nastavení funguje v „tenkém“ režimu a při správné konfiguraci v „tlustém“ režimu. Navíc kód je extrémně jednoduchý:

# Python code using python-oracledb "thin" driver to connect to ADB and execute a SQL query<font></font>
import oracledb<font></font>
import os<font></font>
<font></font>
# Assuming you have your Oracle wallet files in the directory specified in TNS_ADMIN environment variable<font></font>
os.environ["TNS_ADMIN"] = "/path/to/your/wallet_directory"<font></font>
<font></font>
# Construct the connection string. This typically includes the TNS name, which you get from your tnsnames.ora file.<font></font>
connection_string = "user/password@adb_tns_name"<font></font>
<font></font>
try:<font></font>
    # Connect to the database<font></font>
    with oracledb.connect(connection_string) as connection:<font></font>
        # Create a cursor<font></font>
        with connection.cursor() as cursor:<font></font>
            # Execute the SQL query<font></font>
            cursor.execute("SELECT * FROM v$version WHERE banner LIKE 'Oracle%'")<font></font>
            <font></font>
            # Fetch and print the results<font></font>
            for row in cursor:<font></font>
                print("Oracle DB Version:", row[0])<font></font>
<font></font>
except oracledb.Error as e:<font></font>
    print("Oracle-DB error:", e)<font></font>

Všimněte si, že nejprve musíte nainstalovat knihovnu:

pip install oracledb

A abyste povolili „tlustý“ režim, po instalaci klientských knihoven Oracle byste obvykle nastavili proměnnou prostředí takto:

# Set the environment variable to use thick mode<font></font>
os.environ["ORACLEDB_THICK_MODE"] = "TRUE"

Připojení bez řidiče

Alternativně mohou vývojáři zcela obejít tradiční ovladače pomocí Oracle REST Data Services (ORDS) a vytvořit RESTful služby přímo proti ADB. Tento přístup bez ovladače zjednodušuje konektivitu. Dalším podobným přístupem je kombinace REST se standardními ovladači, jako je JDBC  (existují „tenké“ i „tlusté“ verze JDBC ). I když není ovladač „bez ovladače“, je ovladač pro vývojáře transparentní, protože pro operace s databází se používá rámec vyšší úrovně. Můžete například vytvořit rozhraní API s aplikací Spring Boot, která komunikují s ADB přes REST a zpřístupní ji z jakéhokoli prostředí s podporou HTTP.

Závěr

Vývojáři mají několik možností, jak se připojit k autonomní databázi Oracle a pracovat s ní, přičemž každá má vlastní sadu kompromisů. Pokud jste vývojář, musíte zvážit jedinečné požadavky vaší aplikace a kompromisy spojené s každým typem připojení. Zatímco rozdíl mezi „tlustými“ a „tenkými“ ovladači z hlediska výkonu může být závislý na kontextu, s pokrokem v technologii ovladačů mohou „tenké“ ovladače, jako je ovladač JDBC Thin, nabídnout v některých scénářích podobný výkon jako „silné“ ovladače. . „Tlusté“ ovladače mohou být stále preferovány pro jejich přístup k celému spektru funkcí a optimalizací specifických pro Oracle, ale to přichází s režií složitějšího nastavení.

Na druhou stranu použití „tenkých“ ovladačů a připojení „bez ovladače“ poskytuje vývojářům jednoduchost a snadnost použití, což se může promítnout do rychlejších vývojových cyklů, i když by mohly potenciálně omezit přístup k určitým pokročilým funkcím databáze (to však závisí na implementaci ovladače). jak je zmíněno výše).

Pochopením silných stránek a omezení každého přístupu – ať už jde o robustnost a ovládání „tlustých“ ovladačů, snadnost a nedostatek závislostí „tenkých“ ovladačů nebo jednoduchost a agilitu „bez ovladače“ rozhraní REST API – si můžete vybrat nejlepší cesta pro potřeby vaší aplikace a zajištění efektivní a spolehlivé konektivity k vaší autonomní databázi.

Zdroj: Oracle