Sqlalchemy Warning Textual Column Expression Should Be Explicitly Declared?

I keep getting this warning and no matter what can't seem to get rid of it (besides surpressing it):

C:\...\site-packages\sqlalchemy\sql\elements.py:4390: SAWarning:
Textual column expression 'column_name' should be explicitly declared
with text('column_name'), or use column('column_name') for more
specificity 

if guess_is_literal else "column"

I build a list of Column() objects (column name + data type) in one metadata context, and later in another metadata context create a table using this list. While this works, it does give this warning. I've tried:

  • storing it as a "quotedname"
  • casting the column to a "ColumnClause", using column()
  • casting the column to a "TextClause", using text()
  • casting the column to a String, using str()

No matter what, I still get the warning.

Here are a few snippets of the Python code:

for col_name in self.cols_source:
            print(meta.tables[self.table_name].c[col_name].name)
            print(type(meta.tables[self.table_name].c[col_name].name))          #quotedname
            print(type(column(meta.tables[self.table_name].c[col_name].name)))  #ColumnClause
            print(type(text(meta.tables[self.table_name].c[col_name].name)))    #TextClause
            print(type(str(meta.tables[self.table_name].c[col_name].name)))     #Str

            #source_query_cols.append( Column( name=meta.tables[self.table_name].c[col_name].name, type_=meta.tables[self.table_name].c[col_name].type ))
            #source_query_cols.append( Column( name=column(meta.tables[self.table_name].c[col_name].name), type_=meta.tables[self.table_name].c[col_name].type ))
            #source_query_cols.append( Column( name=text(meta.tables[self.table_name].c[col_name].name), type_=meta.tables[self.table_name].c[col_name].type ))
            source_query_cols.append( Column( name=str(meta.tables[self.table_name].c[col_name].name), type_=meta.tables[self.table_name].c[col_name].type ))

5 Answers

You should cast it to text as the error explains. To do so, adapt the following code to your needs :)

from sqlalchemy.sql import text
...
cursor.execute(text(<whatever_needed_to_be_casted>))
1

I faced this issue and I think the problem happens when you do not provide a condition on filter(), e.g instead of declaring filter(model.Email == EmailInput) you declare filter(EmailInput)

2

It seems that you're encountering an issue related to the syntax of your SQLAlchemy query. The error message is suggesting that the column needs to be explicitly defined. Allow me to clarify the correct approach to addressing this issue:

The error arises when you try to include a condition directly within the SQLAlchemy query. Here's an illustration of the incorrect query syntax:

# This query syntax will result in an error
return session.query(cls).filter(
    cls.corelation_id == corelation_id,
    cls.status == cls.ORDER_ACTIVE if not is_cancel else cls.ORDER_CANCEL
).first()

However, the correct way to handle this is by first defining the status condition using a separate variable. Here's the accurate approach:

# Define the status condition based on the 'is_cancel' flag
status = cls.ORDER_ACTIVE if not is_cancel else cls.ORDER_CANCEL

# Use the defined status condition in the SQLAlchemy query
return session.query(cls).filter(
    cls.corelation_id == corelation_id,
    cls.status == status
).first()

In case someone is using where clause, Please make sure you are creating a condition and not just passing the arguments e.g.

from sqlalchemy.orm import Session,aliased
from sqlalchemy import Boolean, Column, DateTime, Integer, String, select,label,func,text,literal_column

 u = aliased(User)
 q = select(u.id).select_from(u).where(u.username == user.username)

Check out

where(u.username == user.username)

I was having the following line

where(u.username, user.username)

and it comes out, it should be

where(u.username == user.username)

1

This warning (or ArgumentError, from v1.3 onwards) is raised when a column name is passed to select (or other functions) as a raw string. Similar warnings may be raised for similar actions, such as passing table names or the right hand side of where/filter calls passed as text. In this answer I am using SQLAlchemy 2.0 syntax, as 1.2.x is no longer supported*.

For example, this

import sqlalchemy as sa

query = sa.select('name').select_from('users')

would raise two exceptions (were that possible), one for the column name in select and one for the table name in select_from.

ArgumentException: Textual column expression 'name' should be explicitly declared with text('name'), or use column('name') for more specificity
ArgumentException: Textual SQL FROM expression 'users' should be explicitly declared as text('users'), or use table('users') for more specificity 

The warning can be addressed by wrapping the strings with the text function:

query = sa.select(sa.text('name')).select_from(sa.text('users'))

or, as the warnings suggests, with column and table functions that make the strings' targets more specific:

query = sa.select(sa.column('name')).select_from(sa.table('users'))

* The differences, for the purpose of this answer are:

  • ArgumentExcaption is raised rather than SAWarning
  • Pre-2.0, select expects a list of arguments, like sa.select(['name'])

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Alexander Ross

Alexander Ross

Gaming, Esports & Interactive Media Writer

Alexander Ross has covered the video game industry for a decade, writing deep dives on game design, esports tournaments, VR developments, and gaming culture.

Share this article
Twitter Facebook Pinterest