datafusion_python/
table.rs1use arrow::pyarrow::ToPyArrow;
19use datafusion::datasource::{TableProvider, TableType};
20use pyo3::prelude::*;
21use std::sync::Arc;
22
23use crate::dataframe::PyDataFrame;
24use crate::dataset::Dataset;
25use crate::utils::table_provider_from_pycapsule;
26
27#[pyclass(frozen, name = "RawTable", module = "datafusion.catalog", subclass)]
31#[derive(Clone)]
32pub struct PyTable {
33 pub table: Arc<dyn TableProvider>,
34}
35
36impl PyTable {
37 pub fn table(&self) -> Arc<dyn TableProvider> {
38 self.table.clone()
39 }
40}
41
42#[pymethods]
43impl PyTable {
44 #[new]
54 pub fn new(obj: &Bound<'_, PyAny>) -> PyResult<Self> {
55 if let Ok(py_table) = obj.extract::<PyTable>() {
56 Ok(py_table)
57 } else if let Ok(py_table) = obj
58 .getattr("_inner")
59 .and_then(|inner| inner.extract::<PyTable>())
60 {
61 Ok(py_table)
62 } else if let Ok(py_df) = obj.extract::<PyDataFrame>() {
63 let provider = py_df.inner_df().as_ref().clone().into_view();
64 Ok(PyTable::from(provider))
65 } else if let Ok(py_df) = obj
66 .getattr("df")
67 .and_then(|inner| inner.extract::<PyDataFrame>())
68 {
69 let provider = py_df.inner_df().as_ref().clone().into_view();
70 Ok(PyTable::from(provider))
71 } else if let Some(provider) = table_provider_from_pycapsule(obj)? {
72 Ok(PyTable::from(provider))
73 } else {
74 let py = obj.py();
75 let provider = Arc::new(Dataset::new(obj, py)?) as Arc<dyn TableProvider>;
76 Ok(PyTable::from(provider))
77 }
78 }
79
80 #[getter]
82 fn schema(&self, py: Python) -> PyResult<PyObject> {
83 self.table.schema().to_pyarrow(py)
84 }
85
86 #[getter]
88 fn kind(&self) -> &str {
89 match self.table.table_type() {
90 TableType::Base => "physical",
91 TableType::View => "view",
92 TableType::Temporary => "temporary",
93 }
94 }
95
96 fn __repr__(&self) -> PyResult<String> {
97 let kind = self.kind();
98 Ok(format!("Table(kind={kind})"))
99 }
100}
101
102impl From<Arc<dyn TableProvider>> for PyTable {
103 fn from(table: Arc<dyn TableProvider>) -> Self {
104 Self { table }
105 }
106}