简体   繁体   中英

Why Does SQLAlchemy Label Columns in Query

When I make a query in SQLAlchemy, I noticed that the queries use the AS keyword for each column. It sets the alias_name = column_name for every column.

For example, if I run the command print(session.query(DefaultLog)) , it returns:

Note: DefaultLog is my table object.

SELECT default_log.id AS default_log_id, default_log.msg AS default_log_msg, default_log.logger_time AS default_log_logger_time, default_log.logger_line AS default_log_logger_line, default_log.logger_filepath AS default_log_logger_filepath, default_log.level AS default_log_level, default_log.logger_name AS default_log_logger_name, default_log.logger_method AS default_log_logger_method, default_log.hostname AS default_log_hostname
FROM default_log

Why does it use an alias = original name? Is there some way I can disable this behavior?

Thank you in advance!

When I make a query in SQLAlchemy, I noticed that the queries use the AS keyword for each column. It sets the alias_name = column_name for every column.

For example, if I run the command print(session.query(DefaultLog)) , it returns:

Note: DefaultLog is my table object.

SELECT default_log.id AS default_log_id, default_log.msg AS default_log_msg, default_log.logger_time AS default_log_logger_time, default_log.logger_line AS default_log_logger_line, default_log.logger_filepath AS default_log_logger_filepath, default_log.level AS default_log_level, default_log.logger_name AS default_log_logger_name, default_log.logger_method AS default_log_logger_method, default_log.hostname AS default_log_hostname
FROM default_log

Why does it use an alias = original name? Is there some way I can disable this behavior?

Thank you in advance!

It is possible to hack sqlachemy Query class to not add labels. But one must be aware that this will breaks when a table is used twice in the query. For example, self join or join thought another table.

from sqlalchemy.orm import Query

class MyQuery(Query):
    def __iter__(self):
        """Patch to disable auto labels"""
        context = self._compile_context(labels=False)
        context.statement.use_labels = False
        if self._autoflush and not self._populate_existing:
            self.session._autoflush()
        return self._execute_and_instances(context)

And then use it according to mtth answer

sessionmaker(bind=engine, query_cls=MyQuery)

Printing an SQLAlchemy query is tricky and produced not human-friendly output. Not only columns but also bind params are in an odd place. Here's how to do it correctly:

qry = session.query(SomeTable)
compiled = qry.statement.compile(dialect=session.bind.dialect, compile_kwargs={"literal_binds": True})
print(compiled)

Here's how to fix it for all your future work:

from sqlalchemy.orm import Query
class MyQuery(Query):
    def __str__(self):
        dialect = self.session.bind.dialect
        compiled = self.statement.compile(dialect=dialect, compile_kwargs={"literal_binds": True})
        return str(compiled)

To use:

session = sessionmaker(bind=engine, query_cls=MyQuery)()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM