superset
superset copied to clipboard
sqlalchemy.exc.ArgumentError
Bug description
When encountering the error sqlalchemy.exc.ArgumentError: Query has only expression-based entities, which do not apply to relationship property "SqlaTable.database" in Superset after logging in, and given that the SQLAlchemy version is 1.4.0, the issue typically arises from a mismatch between the expected model entities and the actual expression-based entities used in the query. This can happen when the ORM is expecting instances of mapped classes but receives SQL expressions instead, which are not compatible with relationship properties defined in the models.
How to reproduce the bug
- login
Screenshots/recordings
Superset version
master / latest-dev
Python version
3.9
Node version
Not applicable
Browser
Chrome
Additional context
SQLAlchemy 1.4.0 SQLAlchemy-Utils 0.38.3 Flask-SQLAlchemy 2.5.0 clickhouse-sqlalchemy 0.2.0
Checklist
- [X] I have searched Superset docs and Slack and didn't find a solution to my problem.
- [X] I have searched the GitHub issue tracker and didn't find a similar bug report.
- [X] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.
@shuailingyi Hello there! I'm here to help you with any bugs, questions, or becoming a contributor. Let's squash those bugs together! 🤖
To resolve the sqlalchemy.exc.ArgumentError related to the "Dashboard.changed_by" relationship property when logging into Superset, ensure that the changed_by property is correctly defined in the Dashboard class. The changed_by property should be defined as a relationship to the User model.
Here is the relevant code snippet from the Dashboard class in superset/models/dashboard.py:
class Dashboard(AuditMixinNullable, ImportExportMixin, Model):
"""The dashboard object!"""
__tablename__ = "dashboards"
id = Column(Integer, primary_key=True)
dashboard_title = Column(String(500))
position_json = Column(utils.MediumText())
description = Column(Text)
css = Column(utils.MediumText())
certified_by = Column(Text)
certification_details = Column(Text)
json_metadata = Column(utils.MediumText())
slug = Column(String(255), unique=True)
slices: list[Slice] = relationship(
Slice, secondary=dashboard_slices, backref="dashboards"
)
owners = relationship(
security_manager.user_model,
secondary=dashboard_user,
passive_deletes=True,
)
tags = relationship(
"Tag",
overlaps="objects,tag,tags",
secondary="tagged_object",
primaryjoin="and_(Dashboard.id == TaggedObject.object_id, "
"TaggedObject.object_type == 'dashboard')",
secondaryjoin="TaggedObject.tag_id == Tag.id",
viewonly=True, # cascading deletion already handled by superset.tags.models.ObjectUpdater.after_delete
)
published = Column(Boolean, default=False)
is_managed_externally = Column(Boolean, nullable=False, default=False)
external_url = Column(Text, nullable=True)
roles = relationship(security_manager.role_model, secondary=DashboardRoles)
embedded = relationship(
"EmbeddedDashboard",
back_populates="dashboard",
cascade="all, delete-orphan",
)
export_fields = [
"dashboard_title",
"position_json",
"json_metadata",
"description",
"css",
"slug",
"certified_by",
"certification_details",
"published",
]
extra_import_fields = ["is_managed_externally", "external_url"]
@property
def changed_by_name(self) -> str:
if not self.changed_by:
return ""
return str(self.changed_by)
Ensure that the changed_by property is correctly defined and linked to the User model. If the changed_by property is missing or incorrectly defined, it can cause the sqlalchemy.exc.ArgumentError [1].
To continue talking to Dosu, mention @dosu.
This has been open/untouched for quite some time, and I'm tempted to close it as stale/inactionable. Can you give us some more reproduction steps besides "login" to go on? Also curious if you're still facing this in 4.1.1 or at all, since there have been a lot of SQL parsing updates made.
We've replaced SQLParse with SQLGlot, and that may have some impact here. Otherwise closeing here for lack of reproduction steps, but happy to revisit if/when needed.