Skip to content

Commit 00a2af6

Browse files
authored
add ODBC usage to README & simplify dependency management (datafusion-contrib#189)
* docs: add ODBC usage to README * chore: simplify dependency management
1 parent 6e42290 commit 00a2af6

49 files changed

Lines changed: 224 additions & 223 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.toml

Lines changed: 61 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,50 @@ license = "Apache-2.0"
88
description = "Extend the capabilities of DataFusion to support additional data sources via implementations of the `TableProvider` trait."
99

1010
[dependencies]
11-
arrow = "53"
12-
arrow-array = { version = "53", optional = true }
13-
arrow-cast = { version = "53", optional = true }
1411
arrow-flight = { version = "53", optional = true, features = [
1512
"flight-sql-experimental",
1613
"tls",
1714
] }
18-
arrow-schema = { version = "53", optional = true, features = ["serde"] }
19-
arrow-json = "53"
20-
async-stream = { version = "0.3.5", optional = true }
21-
async-trait = "0.1.80"
22-
num-bigint = "0.4.4"
23-
bigdecimal = "0.4.5"
15+
arrow-odbc = { version = "14.0", optional = true }
16+
async-stream = { version = "0.3.6", optional = true }
17+
async-trait = "0.1"
18+
bb8 = { version = "0.8", optional = true }
19+
bb8-postgres = { version = "0.8", optional = true }
20+
bigdecimal = "0.4.6"
2421
byteorder = "1.5.0"
2522
chrono = "0.4.38"
26-
datafusion = "43.0.0"
27-
datafusion-expr = { version = "43.0.0", optional = true }
28-
datafusion-physical-expr = { version = "43.0.0", optional = true }
29-
datafusion-physical-plan = { version = "43.0.0", optional = true }
30-
datafusion-proto = { version = "43.0.0", optional = true }
23+
dashmap = "6.1.0"
24+
datafusion = { version = "43", default-features = false }
3125
datafusion-federation = { version = "0.3.1", features = [
3226
"sql",
3327
], optional = true }
28+
datafusion-proto = { version = "43", optional = true }
3429
duckdb = { version = "1.1.1", features = [
3530
"bundled",
3631
"r2d2",
3732
"vtab",
3833
"vtab-arrow",
3934
"appender-arrow",
4035
], optional = true }
36+
dyn-clone = { version = "1.0", optional = true }
4137
fallible-iterator = "0.3.0"
42-
futures = "0.3.30"
43-
mysql_async = { version = "0.34.1", features = [
38+
fundu = "2.0.1"
39+
futures = "0.3"
40+
geo-types = "0.7"
41+
itertools = "0.13.0"
42+
mysql_async = { version = "0.34", features = [
4443
"native-tls-tls",
4544
"chrono",
4645
], optional = true }
47-
prost = { version = "0.13.2", optional = true }
46+
native-tls = { version = "0.2.12", optional = true }
47+
num-bigint = "0.4"
48+
odbc-api = { version = "10.0.0", optional = true }
49+
pem = { version = "3.0.4", optional = true }
50+
postgres-native-tls = { version = "0.5.0", optional = true }
51+
prost = { version = "0.13", optional = true }
4852
r2d2 = { version = "0.8.10", optional = true }
49-
rusqlite = { version = "0.31.0", optional = true }
50-
sea-query = { version = "0.32.0-rc.1", features = [
53+
rusqlite = { version = "0.32.1", optional = true }
54+
sea-query = { version = "0.32.0", features = [
5155
"backend-sqlite",
5256
"backend-postgres",
5357
"postgres-array",
@@ -57,92 +61,72 @@ sea-query = { version = "0.32.0-rc.1", features = [
5761
"with-chrono",
5862
] }
5963
secrecy = "0.8.0"
60-
serde = { version = "1.0.209", optional = true }
61-
serde_json = "1.0.124"
62-
snafu = "0.8.3"
64+
serde = { version = "1.0", optional = true }
65+
serde_json = "1.0"
66+
sha2 = "0.10.8"
67+
snafu = "0.8.5"
6368
time = "0.3.36"
64-
tokio = { version = "1.38.0", features = ["macros", "fs"] }
65-
tokio-util = "0.7.12"
66-
tokio-postgres = { version = "0.7.10", features = [
69+
tokio = { version = "1.41", features = ["macros", "fs"] }
70+
tokio-postgres = { version = "0.7.12", features = [
6771
"with-chrono-0_4",
6872
"with-uuid-1",
6973
"with-serde_json-1",
7074
"with-geo-types-0_7",
7175
], optional = true }
72-
tracing = "0.1.40"
73-
uuid = { version = "1.9.1", optional = true }
74-
postgres-native-tls = { version = "0.5.0", optional = true }
75-
bb8 = { version = "0.8", optional = true }
76-
bb8-postgres = { version = "0.8", optional = true }
77-
native-tls = { version = "0.2.11", optional = true }
78-
trust-dns-resolver = "0.23.2"
79-
url = "2.5.1"
80-
pem = { version = "3.0.4", optional = true }
81-
tokio-rusqlite = { version = "0.5.1", optional = true }
76+
tokio-rusqlite = { version = "0.6.0", optional = true }
8277
tonic = { version = "0.12", optional = true, features = [
8378
"tls-native-roots",
8479
"tls-webpki-roots",
8580
] }
86-
itertools = "0.13.0"
87-
dyn-clone = { version = "1.0.17", optional = true }
88-
geo-types = "0.7.13"
89-
fundu = "2.0.1"
90-
dashmap = "6.1.0"
91-
odbc-api = { version = "9.0.0", optional = true }
92-
arrow-odbc = { version = "13.0.0", optional = true }
93-
sha2 = "0.10.8"
81+
tracing = "0.1.40"
82+
trust-dns-resolver = "0.23.2"
83+
url = "2.5.4"
84+
uuid = { version = "1.11.0", optional = true }
9485

9586
[dev-dependencies]
96-
anyhow = "1.0.86"
97-
bollard = "0.17.1"
98-
rand = "0.8.5"
99-
reqwest = "0.12.5"
100-
secrecy = "0.8.0"
101-
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
102-
test-log = { version = "0.2.16", features = ["trace"] }
103-
rstest = "0.23.0"
87+
anyhow = "1.0"
88+
bollard = "0.18.1"
10489
geozero = { version = "0.14.0", features = ["with-wkb"] }
105-
tokio-stream = { version = "0.1.15", features = ["net"] }
106-
arrow-schema = "53.1.0"
90+
insta = { version = "1.41.1", features = ["filters"] }
10791
prost = { version = "0.13" }
108-
insta = { version = "1.40.0", features = ["filters"] }
92+
rand = "0.8.5"
93+
reqwest = "0.12.9"
94+
rstest = "0.23.0"
95+
test-log = { version = "0.2.16", features = ["trace"] }
96+
tokio-stream = { version = "0.1.16", features = ["net"] }
97+
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
10998

11099
[features]
111-
mysql = ["dep:mysql_async", "dep:async-stream"]
112-
postgres = [
113-
"dep:tokio-postgres",
114-
"dep:uuid",
115-
"dep:postgres-native-tls",
116-
"dep:bb8",
117-
"dep:bb8-postgres",
118-
"dep:native-tls",
119-
"dep:pem",
120-
"dep:async-stream",
121-
]
122-
sqlite = ["dep:rusqlite", "dep:tokio-rusqlite"]
123100
duckdb = [
124101
"dep:duckdb",
125102
"dep:r2d2",
126103
"dep:uuid",
127104
"dep:dyn-clone",
128105
"dep:async-stream",
129106
]
107+
duckdb-federation = ["duckdb", "federation"]
108+
federation = ["dep:datafusion-federation"]
130109
flight = [
131-
"dep:arrow-array",
132-
"dep:arrow-cast",
133110
"dep:arrow-flight",
134-
"dep:arrow-schema",
135-
"dep:datafusion-expr",
136-
"dep:datafusion-physical-expr",
137-
"dep:datafusion-physical-plan",
111+
"datafusion/serde",
138112
"dep:datafusion-proto",
139113
"dep:serde",
140114
"dep:tonic",
141115
]
142-
odbc = ["dep:odbc-api", "dep:arrow-odbc", "dep:async-stream", "dep:dyn-clone"]
143-
federation = ["dep:datafusion-federation"]
144-
duckdb-federation = ["duckdb", "federation"]
145-
sqlite-federation = ["sqlite", "federation"]
146-
postgres-federation = ["postgres", "federation"]
116+
mysql = ["dep:mysql_async", "dep:async-stream"]
147117
mysql-federation = ["mysql", "federation"]
118+
odbc = ["dep:odbc-api", "dep:arrow-odbc", "dep:async-stream", "dep:dyn-clone"]
148119
odbc-federation = ["odbc", "federation"]
120+
postgres = [
121+
"dep:tokio-postgres",
122+
"dep:uuid",
123+
"dep:postgres-native-tls",
124+
"dep:bb8",
125+
"dep:bb8-postgres",
126+
"dep:native-tls",
127+
"dep:pem",
128+
"dep:async-stream",
129+
]
130+
postgres-federation = ["postgres", "federation"]
131+
sqlite = ["dep:rusqlite", "dep:tokio-rusqlite"]
132+
sqlite-federation = ["sqlite", "federation"]

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ let ctx = SessionContext::with_state(state);
2525
- SQLite
2626
- DuckDB
2727
- Flight SQL
28+
- ODBC
2829

2930
## Examples
3031

@@ -100,8 +101,19 @@ cargo run --example mysql --features mysql
100101
```bash
101102
brew install roapi
102103
# or
103-
#cargo install --locked --git https://github.com/roapi/roapi --branch main --bins roapi
104+
# cargo install --locked --git https://github.com/roapi/roapi --branch main --bins roapi
104105
roapi -t taxi=https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2024-01.parquet &
105106

106107
cargo run --example flight-sql --features flight
107108
```
109+
110+
### ODBC
111+
112+
```bash
113+
apt-get install unixodbc-dev libsqliteodbc
114+
# or
115+
# brew install unixodbc & brew install sqliteodbc
116+
# If you use ARM Mac, please see https://github.com/pacman82/odbc-api#os-x-arm--mac-m1
117+
118+
cargo run --example odbc_sqlite --features odbc
119+
```

examples/duckdb.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use std::sync::Arc;
22

33
use datafusion::prelude::SessionContext;
4+
use datafusion::sql::TableReference;
45
use datafusion_table_providers::{
5-
common::DatabaseCatalogProvider,
6+
common::DatabaseCatalogProvider, duckdb::DuckDBTableFactory,
67
sql::db_connection_pool::duckdbpool::DuckDbConnectionPool,
7-
duckdb::DuckDBTableFactory,
88
};
9-
use datafusion::sql::TableReference;
109
use duckdb::AccessMode;
1110

1211
/// This example demonstrates how to:
@@ -17,7 +16,7 @@ use duckdb::AccessMode;
1716
#[tokio::main]
1817
async fn main() {
1918
// Create DuckDB connection pool
20-
// Opening in ReadOnly mode allows multiple reader processes to access
19+
// Opening in ReadOnly mode allows multiple reader processes to access
2120
// the database at the same time
2221
let duckdb_pool = Arc::new(
2322
DuckDbConnectionPool::new_file("examples/duckdb_example.db", &AccessMode::ReadOnly)
@@ -27,7 +26,7 @@ async fn main() {
2726
// Create DuckDB table provider factory
2827
// Used to generate TableProvider instances that can read DuckDB table data
2928
let table_factory = DuckDBTableFactory::new(duckdb_pool.clone());
30-
29+
3130
// Create database catalog provider
3231
// This allows us to access tables through catalog structure (catalog.schema.table)
3332
let catalog = DatabaseCatalogProvider::try_new(duckdb_pool).await.unwrap();

examples/mysql.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ use std::{collections::HashMap, sync::Arc};
33
use datafusion::prelude::SessionContext;
44
use datafusion::sql::TableReference;
55
use datafusion_table_providers::{
6-
common::DatabaseCatalogProvider,
7-
sql::db_connection_pool::mysqlpool::MySQLConnectionPool,
8-
mysql::MySQLTableFactory,
9-
util::secrets::to_secret_map,
6+
common::DatabaseCatalogProvider, mysql::MySQLTableFactory,
7+
sql::db_connection_pool::mysqlpool::MySQLConnectionPool, util::secrets::to_secret_map,
108
};
119

1210
/// This example demonstrates how to:
@@ -54,7 +52,7 @@ async fn main() {
5452
// Create MySQL table provider factory
5553
// Used to generate TableProvider instances that can read MySQL table data
5654
let table_factory = MySQLTableFactory::new(mysql_pool.clone());
57-
55+
5856
// Create database catalog provider
5957
// This allows us to access tables through catalog structure (catalog.schema.table)
6058
let catalog = DatabaseCatalogProvider::try_new(mysql_pool).await.unwrap();

examples/odbc_sqlite.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ async fn main() {
1717
// Create SQLite ODBC connection pool
1818
let params = to_secret_map(HashMap::from([(
1919
"connection_string".to_owned(),
20-
"driver=SQLite3;database=examples/sqlite_example.db;"
21-
.to_owned(),
20+
"driver=SQLite3;database=examples/sqlite_example.db;".to_owned(),
2221
)]));
2322
let odbc_pool =
2423
Arc::new(ODBCPool::new(params).expect("unable to create SQLite ODBC connection pool"));

examples/postgres.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
use std::sync::Arc;
2-
use std::collections::HashMap;
31
use datafusion::prelude::SessionContext;
42
use datafusion::sql::TableReference;
53
use datafusion_table_providers::{
6-
common::DatabaseCatalogProvider,
7-
sql::db_connection_pool::postgrespool::PostgresConnectionPool,
8-
postgres::PostgresTableFactory,
9-
util::secrets::to_secret_map,
4+
common::DatabaseCatalogProvider, postgres::PostgresTableFactory,
5+
sql::db_connection_pool::postgrespool::PostgresConnectionPool, util::secrets::to_secret_map,
106
};
7+
use std::collections::HashMap;
8+
use std::sync::Arc;
119

1210
/// This example demonstrates how to:
1311
/// 1. Create a PostgreSQL connection pool
@@ -54,10 +52,12 @@ async fn main() {
5452
// Create PostgreSQL table provider factory
5553
// Used to generate TableProvider instances that can read PostgreSQL table data
5654
let table_factory = PostgresTableFactory::new(postgres_pool.clone());
57-
55+
5856
// Create database catalog provider
5957
// This allows us to access tables through catalog structure (catalog.schema.table)
60-
let catalog = DatabaseCatalogProvider::try_new(postgres_pool).await.unwrap();
58+
let catalog = DatabaseCatalogProvider::try_new(postgres_pool)
59+
.await
60+
.unwrap();
6161

6262
// Create DataFusion session context
6363
let ctx = SessionContext::new();

examples/sqlite.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ async fn main() {
3232
// Create SQLite table provider factory
3333
// Used to generate TableProvider instances that can read SQLite table data
3434
let table_factory = SqliteTableFactory::new(sqlite_pool.clone());
35-
35+
3636
// Create database catalog provider
3737
// This allows us to access tables through catalog structure (catalog.schema.table)
3838
let catalog_provider = DatabaseCatalogProvider::try_new(sqlite_pool).await.unwrap();

src/duckdb.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use crate::util::{
1717
indexes::IndexType,
1818
on_conflict::{self, OnConflict},
1919
};
20-
use arrow::{array::RecordBatch, datatypes::SchemaRef};
2120
use async_trait::async_trait;
21+
use datafusion::arrow::{array::RecordBatch, datatypes::SchemaRef};
2222
use datafusion::{
2323
catalog::{Session, TableProviderFactory},
2424
common::Constraints,

src/duckdb/creator.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::sql::arrow_sql_gen::statement::IndexBuilder;
22
use crate::sql::db_connection_pool::duckdbpool::DuckDbConnectionPool;
3-
use arrow::{array::RecordBatch, datatypes::SchemaRef};
3+
use datafusion::arrow::{array::RecordBatch, datatypes::SchemaRef};
44
use datafusion::common::Constraints;
55
use duckdb::{vtab::arrow_recordbatch_to_query_params, ToSql, Transaction};
66
use snafu::prelude::*;
@@ -322,7 +322,7 @@ pub(crate) mod tests {
322322
use crate::sql::db_connection_pool::{
323323
dbconnection::duckdbconn::DuckDbConnection, duckdbpool::DuckDbConnectionPool,
324324
};
325-
use arrow::array::RecordBatch;
325+
use datafusion::arrow::array::RecordBatch;
326326
use datafusion::{
327327
execution::{SendableRecordBatchStream, TaskContext},
328328
parquet::arrow::arrow_reader::ParquetRecordBatchReaderBuilder,
@@ -358,7 +358,7 @@ pub(crate) mod tests {
358358
.expect("to build parquet reader");
359359

360360
parquet_reader
361-
.collect::<Result<Vec<_>, arrow::error::ArrowError>>()
361+
.collect::<Result<Vec<_>, datafusion::arrow::error::ArrowError>>()
362362
.expect("to get records")
363363
}
364364

src/duckdb/federation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::sql::db_connection_pool::dbconnection::{get_schema, Error as DbError};
22
use crate::sql::sql_provider_datafusion::{get_stream, to_execution_error};
3-
use arrow::datatypes::SchemaRef;
3+
use datafusion::arrow::datatypes::SchemaRef;
44
use datafusion::sql::unparser::dialect::Dialect;
55
use datafusion_federation::sql::{SQLExecutor, SQLFederationProvider, SQLTableSource};
66
use datafusion_federation::{FederatedTableProviderAdaptor, FederatedTableSource};

0 commit comments

Comments
 (0)