Skip to content

Commit 1b2ba5f

Browse files
committed
chore: prepare for release
Letsql uses maturin as the build-backend. To handle our dependencies we use poetry. As of now, and in the future, maturin does not recognize the dependencies specified by poetry see this issue: PyO3/maturin#632 It also does not provide an alternative way to support dynamic dependencies The following issue is still open PyO3/maturin#1537 On the other side poetry will support PEP-621 project style dependencies in the version 2.0 python-poetry/poetry#3332 Therefore one simple solution is to duplicate the dependencies section, as in the package: https://github.com/tmtenbrink/rustfrc/blob/main/pyproject.toml To do so, a semi-automated approach is to generate the dependencies using poetry export poetry export -f requirements.txt --without="test,dev,docs" / --all-extras --without-hashes --output requirements.txt And then update the dependencies section in the pyproject.toml file. Additionally this commit solves a few inconsistencies regarding packages listed as optional (duckdb, ibis), but when running the code it gives errors.
1 parent 37df954 commit 1b2ba5f

File tree

6 files changed

+83
-8
lines changed

6 files changed

+83
-8
lines changed

poetry.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+32
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,27 @@ build-backend = "maturin"
55
[project]
66
name = "letsql"
77
dynamic = ["version"]
8+
dependencies = [
9+
"ibis-framework==9.0.0 ; python_version >= '3.10' and python_version < '4.0'",
10+
"dask==2023.12.1 ; python_version >= '3.10' and python_version < '4.0'",
11+
"attrs==23.2.0 ; python_version >= '3.10' and python_version < '4.0'",
12+
"connectorx==0.3.2 ; python_version >= '3.10' and python_version < '4.0'",
13+
"psycopg2-binary==2.9.9 ; python_version >= '3.10' and python_version < '4.0'",
14+
"sqlalchemy==2.0.29 ; python_version >= '3.10' and python_version < '4.0'",
15+
"pyarrow==13.0.0 ; python_version >= '3.10' and python_version < '4.0'",
16+
"palmerpenguins==0.1.4 ; python_version >= '3.10' and python_version < '4.0'",
17+
"structlog==24.2.0 ; python_version >= '3.10' and python_version < '4.0'",
18+
"pytest-mock==3.14.0 ; python_version >= '3.10' and python_version < '4.0'",
19+
]
820
requires-python = ">=3.7"
21+
authors = [
22+
{ name = "Hussain Sultan", email = "[email protected]" },
23+
]
24+
maintainers = [
25+
{ email = "Dan Lovell <[email protected]>" },
26+
{ email = "Daniel Mesejo <[email protected]>" },
27+
]
28+
description = "Data processing library built on top of Ibis and DataFusion to write multi-engine data workflows."
929
readme = "README.md"
1030
license = { file = "LICENSE" }
1131
classifiers = [
@@ -25,6 +45,18 @@ Repository = "https://github.com/letsql/letsql.git"
2545
Issues = "https://github.com/letsql/letsql/issues"
2646
Changelog = "https://github.com/letsql/letsql/blob/main/CHANGELOG.md"
2747

48+
[project.optional-dependencies]
49+
duckb = [
50+
"duckdb==0.10.3 ; python_version >= '3.10' and python_version < '4.0'"
51+
]
52+
datafusion = [
53+
"datafusion==34.0.0 ; python_version >= '3.10' and python_version < '4.0'"
54+
]
55+
snowflake = [
56+
"snowflake-connector-python==3.10.1 ; python_version >= '3.10' and python_version < '4.0'"
57+
]
58+
59+
2860
[tool.maturin]
2961
module-name = "letsql._internal"
3062
python-source = "python"

python/letsql/backends/let/__init__.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
from ibis import BaseBackend
1010
from ibis.expr import types as ir
1111
from ibis.expr.schema import SchemaLike
12-
from ibis.backends.datafusion import Backend as IbisDataFusionBackend
1312
from sqlglot import exp, parse_one
1413

1514
import letsql.backends.let.hotfix # noqa: F401
@@ -64,7 +63,10 @@ def register(
6463
table_or_expr = self._sources.get_table_or_op(table_or_expr)
6564
backend = self._sources.get_backend(table_or_expr)
6665

67-
if isinstance(backend, (DataFusionBackend, IbisDataFusionBackend)):
66+
if (
67+
isinstance(backend, DataFusionBackend)
68+
or getattr(backend, "name", "") == DataFusionBackend.name
69+
):
6870
source = _get_datafusion_dataframe(backend, source)
6971

7072
registered_table = super().register(source, table_name=table_name, **kwargs)

python/letsql/common/utils/dask_normalize_expr.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import ibis.expr.operations.relations as ir
66
import sqlglot as sg
77

8+
import letsql
89
from letsql.expr.relations import (
910
make_native_op,
1011
)
@@ -18,15 +19,12 @@ def expr_is_bound(expr):
1819
def unbound_expr_to_default_sql(expr):
1920
if expr_is_bound(expr):
2021
raise ValueError
21-
default_sql = ibis.to_sql(
22-
expr,
23-
dialect=ibis.options.sql.default_dialect,
24-
)
22+
default_sql = letsql.to_sql(expr)
2523
return str(default_sql)
2624

2725

2826
def normalize_memory_databasetable(dt):
29-
if dt.source.name not in ("pandas", "datafusion", "duckdb"):
27+
if dt.source.name not in ("pandas", "let", "datafusion", "duckdb"):
3028
raise ValueError
3129
return dask.base._normalize_seq_func(
3230
(
@@ -175,7 +173,7 @@ def normalize_backend(con):
175173
con_details = {k: con_dct[k] for k in ("host", "port", "dbname")}
176174
elif name == "pandas":
177175
con_details = id(con.dictionary)
178-
elif name in ("datafusion", "duckdb"):
176+
elif name in ("datafusion", "duckdb", "let"):
179177
con_details = id(con.con)
180178
else:
181179
raise ValueError

python/letsql/config.py

+14
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,19 @@ class Repr(Config):
8484
interactive: Interactive = Interactive()
8585

8686

87+
class SQL(Config):
88+
"""SQL-related options.
89+
90+
Attributes
91+
----------
92+
dialect : str
93+
Dialect to use for printing SQL when the backend cannot be determined.
94+
95+
"""
96+
97+
dialect: str = "datafusion"
98+
99+
87100
class Options(Config):
88101
"""LETSQL configuration options
89102
@@ -100,6 +113,7 @@ class Options(Config):
100113
cache: Cache = Cache()
101114
backend: Optional[Any] = None
102115
repr: Repr = Repr()
116+
sql: SQL = SQL()
103117

104118
@property
105119
def interactive(self) -> bool:

python/letsql/expr/api.py

+27
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
import ibis.expr.schema as sch
1414
import ibis.expr.types as ir
1515
from ibis import api
16+
from ibis.backends.sql.dialects import DataFusion
1617
from ibis.common.deferred import Deferred, _, deferrable
1718
from ibis.expr.schema import Schema
19+
from ibis.expr.sql import SQLString
1820
from ibis.expr.types import (
1921
Column,
2022
DateValue,
@@ -90,6 +92,7 @@
9092
"table",
9193
"time",
9294
"today",
95+
"to_sql",
9396
"timestamp",
9497
"union",
9598
"uuid",
@@ -1515,3 +1518,27 @@ def interval(
15151518
microseconds=microseconds,
15161519
nanoseconds=nanoseconds,
15171520
)
1521+
1522+
1523+
def to_sql(expr: ir.Expr, pretty: bool = True) -> SQLString:
1524+
"""Return the formatted SQL string for an expression.
1525+
1526+
Parameters
1527+
----------
1528+
expr
1529+
Ibis expression.
1530+
pretty
1531+
Whether to use pretty formatting.
1532+
1533+
Returns
1534+
-------
1535+
str
1536+
Formatted SQL string
1537+
1538+
"""
1539+
from letsql.config import _backend_init
1540+
1541+
con = _backend_init()
1542+
sg_expr = con._to_sqlglot(expr.unbind())
1543+
sql = sg_expr.sql(dialect=DataFusion, pretty=pretty)
1544+
return SQLString(sql)

0 commit comments

Comments
 (0)