I have a Declarative base defined as follows:
class User(Base):
__tablename__ = "gold.user"
__table_args__ = {"quote": False}
user= Column("user", String, primary_key=True)
I'm querying the table using the following line of code:
session.query(User.user).limit(1)
However, the generated query has an undesired format, like this:
SELECT gold.user.`user` as
gold.user_user
FROM gold.user
LIMIT 1
I want to remove the table name from the column name and also get rid of the alias to maintain the original naming. This is how the desired query looks like:
SELECT user
FROM gold.user
LIMIT 1
How can I achieve this?
There are two parts to this: the alias, or label and the schema.table qualifier.
SQLAlchemy provides label styles that can be applied to the label:
with orm.Session(engine) as s:
print('Legacy query')
s.query(User.user).set_label_style(sa.LABEL_STYLE_NONE).limit(1).first()
print('2.0 style')
s.scalars(
sa.select(User.user)
.set_label_style(sa.SelectLabelStyle.LABEL_STYLE_NONE)
.limit(1)
).first()
The qualifiers are more difficult to adjust. When a column is compiled into SQL, the presence of the qualifier (in the simple case) is governed by the include_table keyword argument. This argument defaults to True
, meaning the qualifier is applied. If you want to override it, you could intercept column compilation like this:
import sqlalchemy as sa
from sqlalchemy.ext.compiler import compiles
@compiles(sa.Column)
def format_column(element, compiler, **kw):
kw['include_table'] = False
return compiler.visit_column(element, **kw)
This is obviously indiscriminate and could cause problems if a column needs to be qualified.
Finally, user
is enclosed in double quotes because it is a reserved word in PostgreSQL - this quoting is unavoidable if you want a syntactically correct statement.