<p dir="auto">Cast renders an anonymous alias contrary to the <a href="https://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql.expression.cast" rel="nofollow">documentation</a></p>
<p dir="auto">The example used in the documantation</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="from sqlalchemy import cast, Numeric, select

stmt = select([
            cast(product_table.c.unit_price, Numeric(10, 4))
        ])"><pre class="notranslate"><span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span> <span class="pl-k">import</span> <span class="pl-s1">cast</span>, <span class="pl-v">Numeric</span>, <span class="pl-s1">select</span>

<span class="pl-s1">stmt</span> <span class="pl-c1">=</span> <span class="pl-en">select</span>([
            <span class="pl-en">cast</span>(<span class="pl-s1">product_table</span>.<span class="pl-s1">c</span>.<span class="pl-s1">unit_price</span>, <span class="pl-v">Numeric</span>(<span class="pl-c1">10</span>, <span class="pl-c1">4</span>))
        ])</pre></div>
<p dir="auto">renders as</p>
<div class="highlight highlight-source-sql notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="SELECT CAST(product_table.unit_price AS NUMERIC(10, 4)) AS anon_1 FROM product_table"><pre class="notranslate"><span class="pl-k">SELECT</span> CAST(<span class="pl-c1">product_table</span>.<span class="pl-c1">unit_price</span> <span class="pl-k">AS</span> <span class="pl-k">NUMERIC</span>(<span class="pl-c1">10</span>, <span class="pl-c1">4</span>)) <span class="pl-k">AS</span> anon_1 <span class="pl-k">FROM</span> product_table</pre></div>
<p dir="auto">instead of</p>
<div class="highlight highlight-source-sql notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="SELECT CAST(unit_price AS NUMERIC(10, 4)) FROM product"><pre class="notranslate"><span class="pl-k">SELECT</span> CAST(unit_price <span class="pl-k">AS</span> <span class="pl-k">NUMERIC</span>(<span class="pl-c1">10</span>, <span class="pl-c1">4</span>)) <span class="pl-k">FROM</span> product</pre></div>
<p dir="auto">I've tried sqlalchemy version 1.2.7 and 1.2.16 and both return the same result</p>
<p dir="auto">We're having some issues with <code class="notranslate">back_populates</code> of relationships referring to other relationships with <code class="notranslate">viewonly=True</code>. We get duplicates in the relationship list that the <code class="notranslate">back_populates</code> refers to.  Test case:</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import sqlalchemy
from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import attributes
from sqlalchemy.orm import relationship

Base = declarative_base()


class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    boston_addresses = relationship(
        &quot;Address&quot;,
        # primaryjoin=&quot;and_(User.id==Address.user_id, Address.city=='Boston')&quot;,  # Not necessary but shows the use case
        viewonly=True)  # Setting viewonly = False prevents the issue


class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('user.id'))
    user = relationship('User', back_populates='boston_addresses')

    city = Column(String)


def main():
    session = setup_database_and_session()

    user = User()

    session.add(user)
    session.commit()

    # user.boston_addresses   # Reading the value here prevents the issue

    address = Address(user=user, city='Boston')
    
    actual = user.boston_addresses
    expected = [address]
    assert actual == expected, f&quot;{actual} != {expected}&quot;


def setup_database_and_session():
    engine = sqlalchemy.create_engine(&quot;sqlite://&quot;)
    session_maker = sqlalchemy.orm.sessionmaker(bind=engine)
    session = session_maker()
    Base.metadata.create_all(engine)
    return session


if __name__ == &quot;__main__&quot;:
    main()"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">sqlalchemy</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span> <span class="pl-k">import</span> <span class="pl-v">Column</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span> <span class="pl-k">import</span> <span class="pl-v">ForeignKey</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span> <span class="pl-k">import</span> <span class="pl-v">Integer</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span> <span class="pl-k">import</span> <span class="pl-v">String</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span>.<span class="pl-s1">ext</span>.<span class="pl-s1">declarative</span> <span class="pl-k">import</span> <span class="pl-s1">declarative_base</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span>.<span class="pl-s1">orm</span> <span class="pl-k">import</span> <span class="pl-s1">attributes</span>
<span class="pl-k">from</span> <span class="pl-s1">sqlalchemy</span>.<span class="pl-s1">orm</span> <span class="pl-k">import</span> <span class="pl-s1">relationship</span>

<span class="pl-v">Base</span> <span class="pl-c1">=</span> <span class="pl-en">declarative_base</span>()


<span class="pl-k">class</span> <span class="pl-v">User</span>(<span class="pl-v">Base</span>):
    <span class="pl-s1">__tablename__</span> <span class="pl-c1">=</span> <span class="pl-s">'user'</span>
    <span class="pl-s1">id</span> <span class="pl-c1">=</span> <span class="pl-v">Column</span>(<span class="pl-v">Integer</span>, <span class="pl-s1">primary_key</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)
    <span class="pl-s1">name</span> <span class="pl-c1">=</span> <span class="pl-v">Column</span>(<span class="pl-v">String</span>)
    <span class="pl-s1">boston_addresses</span> <span class="pl-c1">=</span> <span class="pl-en">relationship</span>(
        <span class="pl-s">"Address"</span>,
        <span class="pl-c"># primaryjoin="and_(User.id==Address.user_id, Address.city=='Boston')",  # Not necessary but shows the use case</span>
        <span class="pl-s1">viewonly</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)  <span class="pl-c"># Setting viewonly = False prevents the issue</span>


<span class="pl-k">class</span> <span class="pl-v">Address</span>(<span class="pl-v">Base</span>):
    <span class="pl-s1">__tablename__</span> <span class="pl-c1">=</span> <span class="pl-s">'address'</span>
    <span class="pl-s1">id</span> <span class="pl-c1">=</span> <span class="pl-v">Column</span>(<span class="pl-v">Integer</span>, <span class="pl-s1">primary_key</span><span class="pl-c1">=</span><span class="pl-c1">True</span>)
    <span class="pl-s1">user_id</span> <span class="pl-c1">=</span> <span class="pl-v">Column</span>(<span class="pl-v">Integer</span>, <span class="pl-v">ForeignKey</span>(<span class="pl-s">'user.id'</span>))
    <span class="pl-s1">user</span> <span class="pl-c1">=</span> <span class="pl-en">relationship</span>(<span class="pl-s">'User'</span>, <span class="pl-s1">back_populates</span><span class="pl-c1">=</span><span class="pl-s">'boston_addresses'</span>)

    <span class="pl-s1">city</span> <span class="pl-c1">=</span> <span class="pl-v">Column</span>(<span class="pl-v">String</span>)


<span class="pl-k">def</span> <span class="pl-en">main</span>():
    <span class="pl-s1">session</span> <span class="pl-c1">=</span> <span class="pl-en">setup_database_and_session</span>()

    <span class="pl-s1">user</span> <span class="pl-c1">=</span> <span class="pl-v">User</span>()

    <span class="pl-s1">session</span>.<span class="pl-en">add</span>(<span class="pl-s1">user</span>)
    <span class="pl-s1">session</span>.<span class="pl-en">commit</span>()

    <span class="pl-c"># user.boston_addresses   # Reading the value here prevents the issue</span>

    <span class="pl-s1">address</span> <span class="pl-c1">=</span> <span class="pl-v">Address</span>(<span class="pl-s1">user</span><span class="pl-c1">=</span><span class="pl-s1">user</span>, <span class="pl-s1">city</span><span class="pl-c1">=</span><span class="pl-s">'Boston'</span>)
    
    <span class="pl-s1">actual</span> <span class="pl-c1">=</span> <span class="pl-s1">user</span>.<span class="pl-s1">boston_addresses</span>
    <span class="pl-s1">expected</span> <span class="pl-c1">=</span> [<span class="pl-s1">address</span>]
    <span class="pl-k">assert</span> <span class="pl-s1">actual</span> <span class="pl-c1">==</span> <span class="pl-s1">expected</span>, <span class="pl-s">f"<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">actual</span><span class="pl-kos">}</span></span> != <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">expected</span><span class="pl-kos">}</span></span>"</span>


<span class="pl-k">def</span> <span class="pl-en">setup_database_and_session</span>():
    <span class="pl-s1">engine</span> <span class="pl-c1">=</span> <span class="pl-s1">sqlalchemy</span>.<span class="pl-en">create_engine</span>(<span class="pl-s">"sqlite://"</span>)
    <span class="pl-s1">session_maker</span> <span class="pl-c1">=</span> <span class="pl-s1">sqlalchemy</span>.<span class="pl-s1">orm</span>.<span class="pl-en">sessionmaker</span>(<span class="pl-s1">bind</span><span class="pl-c1">=</span><span class="pl-s1">engine</span>)
    <span class="pl-s1">session</span> <span class="pl-c1">=</span> <span class="pl-en">session_maker</span>()
    <span class="pl-v">Base</span>.<span class="pl-s1">metadata</span>.<span class="pl-en">create_all</span>(<span class="pl-s1">engine</span>)
    <span class="pl-k">return</span> <span class="pl-s1">session</span>


<span class="pl-k">if</span> <span class="pl-s1">__name__</span> <span class="pl-c1">==</span> <span class="pl-s">"__main__"</span>:
    <span class="pl-en">main</span>()</pre></div>
<p dir="auto">Result:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="AssertionError: [&lt;__main__.Address object at 0x10d95aeb8&gt;, &lt;__main__.Address object at 0x10d95aeb8&gt;] != [&lt;__main__.Address object at 0x10d95aeb8&gt;]"><pre class="notranslate"><code class="notranslate">AssertionError: [&lt;__main__.Address object at 0x10d95aeb8&gt;, &lt;__main__.Address object at 0x10d95aeb8&gt;] != [&lt;__main__.Address object at 0x10d95aeb8&gt;]
</code></pre></div>