Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
246 views
in Technique[技术] by (71.8m points)

python - 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!

question from:https://stackoverflow.com/questions/65858533/sqlalchemy-disable-default-renaming

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Query.statement:

The full SELECT statement represented by this Query.

The statement by default will not have disambiguating labels applied to the construct unless with_labels(True) is called first.

Using this model:

class DefaultLog(Base):

    id = sa.Column(sa.Integer, primary_key=True)
    msg = sa.Column(sa.String(128))
    logger_time = sa.Column(sa.DateTime)
    logger_line = sa.Column(sa.Integer)

print(session.query(DefaultLog).statement) shows:

SELECT defaultlog.id, defaultlog.msg, defaultlog.logger_time, defaultlog.logger_line
FROM defaultlog

print(session.query(DefaultLog).with_labels().statement) shows:

SELECT defaultlog.id AS defaultlog_id, defaultlog.msg AS defaultlog_msg, defaultlog.logger_time AS defaultlog_logger_time, defaultlog.logger_line AS defaultlog_logger_line
FROM defaultlog

You asked:

Why does it use an alias = original name?

From Query.with_labels docs:

...this is commonly used to disambiguate columns from multiple tables which have the same name.

So if you want to issue a single query that calls upon multiple tables, there is nothing stopping those tables having columns that share the same name.

Is there some way I can disable this behavior?

Also from the Query.with_labels docs:

When the Query actually issues SQL to load rows, it always uses column labeling.

All of the methods that retrieve rows (get(), one(), one_or_none(), all() and iterating over the Query) route through the Query.__iter__() method:

def __iter__(self):
    context = self._compile_context()
    context.statement.use_labels = True
    if self._autoflush and not self._populate_existing:
        self.session._autoflush()
    return self._execute_and_instances(context)

... where this line hard codes the label usage: context.statement.use_labels = True. So it is "baked in" and can't be disabled.

You can execute the statement without labels:

session.execute(session.query(DefaultLog).statement)

... but that takes the ORM out of the equation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...