-
Notifications
You must be signed in to change notification settings - Fork 892
feat(sql): respect display.dataframes config setting #8053
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(sql): respect display.dataframes config setting #8053
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
All contributors have signed the CLA ✍️ ✅ |
marimo/_sql/sql.py
Outdated
| if SQLAlchemyEngine.is_cursor_result(df): | ||
| display_df = SQLAlchemyEngine.get_cursor_metadata(df) | ||
| elif DBAPIEngine.is_dbapi_cursor(df): | ||
| display_df = DBAPIEngine.get_cursor_metadata(df) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is some duplicate code from below:
if SQLAlchemyEngine.is_cursor_result(df):
display_df = SQLAlchemyEngine.get_cursor_metadata(df)
elif DBAPIEngine.is_dbapi_cursor(df):
display_df = DBAPIEngine.get_cursor_metadata(df)
you might be able to do to t = plain(display_df) (plain will run back through our formatters, but skip making them pretty dataframes)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion! A minimal elif instead of the long manual handling. The pull request has been updated with a simplified implementation.
|
I have read the CLA Document and I hereby sign the CLA |
44a1124 to
2351f7d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you be able to add some tests? Probably under test_sql.py, may need to mock different return values of include_opinionated()
marimo/_sql/sql.py
Outdated
| # Respect display.dataframes config - use plain formatting | ||
| from marimo._output.formatting import plain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it'd be better to move this import to below if output for consistency. In general I'd prefer moving all imports to top of the file, but for lazy loading and consistency, could move it below output imo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
When display.dataframes is set to 'plain', mo.sql() now uses plain() to format output instead of the rich interactive table viewer. This makes SQL cell output consistent with regular DataFrame display behavior when the user has configured plain table output.
2351f7d to
fd20940
Compare
- test_sql_plain_output_when_not_opinionated: verifies Plain object is used - test_sql_rich_output_when_opinionated: verifies table is used
Forcepushed tests. |
- Call replace() directly in each branch instead of assigning to shared variable 't' to avoid Plain vs Html type incompatibility - Add missing _mock_include_opinionated parameter to test methods that use multiple @patch decorators
787afd9 to
691c840
Compare
Light2Dark
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a few touch ups, i think it looks good!
| import duckdb | ||
| import polars as pl | ||
|
|
||
| from marimo._output.formatting import Plain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better to move this import to the top of file. It's in a test file so it's fine.
| from marimo._output.formatting import Plain | ||
|
|
||
| # Create a test table | ||
| duckdb.sql( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to just do sql("SELECT 1"). We don't need to create & drop a new table for this.
tests/_sql/test_sql.py
Outdated
| class TestDisplayConfigBehavior: | ||
| """Test that sql() respects the display.dataframes config setting.""" | ||
|
|
||
| @pytest.mark.usefixtures("_mock_include_opinionated") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, this test seems to fail for me. The fixture cannot be found (not sure if/how CI passes)
You can patch it in the code itself for simplicity
@patch("marimo._sql.sql.replace")
@patch("marimo._output.formatters.df_formatters.include_opinionated")
@pytest.mark.skipif(
not HAS_POLARS or not HAS_DUCKDB, reason="polars and duckdb required"
)
def test_sql_plain_output_when_not_opinionated(
self, mock_include_opinionated, mock_replace
):
"""Test that SQL uses plain() when include_opinionated returns False."""
mock_include_opinionated.return_value = False
import polars as pl
from marimo._output.formatting import Plain
# Test query
result = sql("SELECT 1")
assert isinstance(result, pl.DataFrame)
# Should call replace with Plain object
mock_replace.assert_called_once()
call_args = mock_replace.call_args[0][0]
# The call should be a Plain object (not a table)
assert isinstance(call_args, Plain)Each @patch decorator injects a mock argument into the test function. The previous fix removed these parameters causing signature mismatch. Restored _mock_opinionated parameter (underscore-prefixed for ruff) and removed the usefixtures decorator referencing non-existent fixture.
for more information, see https://pre-commit.ci
Summary
When
display.dataframesis set to"plain",mo.sql()now usesplain()to format output instead of the rich interactive table viewer.This makes SQL cell output consistent with regular DataFrame display behavior when the user has configured plain table output.
Changes
include_opinionated()inmarimo/_sql/sql.pybefore creating table outputinclude_opinionated()returnsFalse(plain mode), usesplain(df)instead oftable.table()Testing
Added tests in
tests/_sql/test_sql.py:test_sql_plain_output_when_not_opinionated: Verifies thatPlainobject is used wheninclude_opinionated()returnsFalsetest_sql_rich_output_when_opinionated: Verifies thattableis used wheninclude_opinionated()returnsTrueBoth tests mock
include_opinionated()and verify the correct output type is passed toreplace().