the query emitted is:

SELECT tb_nv.id, min(bs_3.build_id) AS min_1
FROM tb_nv, tb_brst AS bs_3, tb_brst AS bs
INNER JOIN tb_vers AS v_2 ON bs.version_id = v_2.id
INNER JOIN tb_brst AS bs_2 ON tb_br.id = bs_2.branch_id

the error means that your ON clause refers to a table "tb_br" which is not 
otherwise in the FROM clause: "ON tb_br.id = bs_2.branch_id"

the ON clause can only refer to columns from tables that are being SELECTed 
from, such as:

SELECT tb_nv.id, min(bs_3.build_id) AS min_1
FROM tb_nv, tb_brst AS bs_3, tb_brst AS bs
INNER JOIN tb_vers AS v_2 ON bs.version_id = v_2.id
INNER JOIN tb_br ON tb_br.id = bs_2.branch_id
INNER JOIN tb_brst AS bs_2 ON tb_br.id = bs_2.branch_id

so you'd need to alter your query to include some indication how tb_br is part 
of what's being joined.

On Fri, Mar 17, 2023, at 7:52 PM, 'Dan Stromberg' via sqlalchemy wrote:
> 
> Hi people.
> 
> I'm having trouble with a test query.
> 
> As the subject line says, I'm getting:
> sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1054, "Unknown 
> column 'tb_br.id' in 'on clause'")
> 
> But it seems like tb_br exists, and has an id column - tb_br being an empty 
> table, but still, existent:
> mysql> show create table tb_br;
> +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
> | Table | Create Table                                                        
>                                                                               
>       |
> +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
> | tb_br | CREATE TABLE `tb_br` (
>   `id` int(11) NOT NULL AUTO_INCREMENT,
>   `name` varchar(45) NOT NULL,
>   PRIMARY KEY (`id`)
> ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
> +-------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
> 1 row in set (0.04 sec)
> 
> mysql> select * from tb_br;
> Empty set (0.03 sec)
> 
> The query, along with sample models, looks like:
> #!/usr/bin/env python3
> 
> """
> A little test program.
> 
> Environment variables:
>     DBU  Your database user
>     DBP  Your database password
>     DBH  Your database host
>     IDB  Your initial database
> """
> 
> import os
> import pprint
> 
> from sqlalchemy import create_engine, select
> from sqlalchemy.orm import aliased, sessionmaker, declarative_base
> from sqlalchemy.sql.expression import func
> from flask_sqlalchemy import SQLAlchemy
> 
> db = SQLAlchemy()
> Base = declarative_base()
> 
> 
> class NV(Base):
>     __tablename__ = "tb_nv"
>     __bind_key__ = "testdb"
>     __table_args__ = (
>         {
>             "mysql_engine": "InnoDB",
>             "mysql_charset": "utf8",
>             "mysql_collate": "utf8_general_ci",
>         },
>     )
> 
>     id = db.Column("id", db.Integer, primary_key=True, autoincrement=True)
>     builds = db.relationship("Bld", primaryjoin="(NV.id == Bld.variant_id)")
> 
> 
> class Vers(Base):
>     __tablename__ = "tb_vers"
>     __bind_key__ = "testdb"
>     __table_args__ = (
>         {
>             "mysql_engine": "InnoDB",
>             "mysql_charset": "utf8",
>             "mysql_collate": "utf8_general_ci",
>         },
>     )
> 
>     id = db.Column("id", db.Integer, primary_key=True, autoincrement=True)
> 
> 
> class St(Base):
>     __tablename__ = "tb_brst"
>     __bind_key__ = "testdb"
>     __table_args__ = ({"mysql_engine": "InnoDB", "mysql_charset": "utf8"},)
> 
>     id = db.Column("id", db.Integer, primary_key=True, autoincrement=True)
>     version_id = db.Column(
>         "version_id",
>         db.Integer,
>         db.ForeignKey(
>             "tb_vers.id",
>             name="fk_tb_brst_version_id",
>             onupdate="CASCADE",
>             ondelete="RESTRICT",
>         ),
>         nullable=False,
>     )
>     branch_id = db.Column(
>         "branch_id",
>         db.Integer,
>         db.ForeignKey(
>             "tb_br.id",
>             name="fk_tb_brst_branch_id",
>             onupdate="CASCADE",
>             ondelete="RESTRICT",
>         ),
>         nullable=False,
>     )
>     build_id = db.Column(
>         "build_id",
>         db.Integer,
>         db.ForeignKey(
>             "tb_bld.id",
>             name="fk_tb_brst_build_id",
>             onupdate="CASCADE",
>             ondelete="RESTRICT",
>         ),
>         nullable=False,
>     )
> 
>     version = db.relationship(
>         "Vers", innerjoin=True, primaryjoin="(St.version_id == Vers.id)"
>     )
>     branch = db.relationship(
>         "Br", innerjoin=True, primaryjoin="(St.branch_id == Br.id)"
>     )
>     build = db.relationship(
>         "Bld", innerjoin=True, primaryjoin="(St.build_id == Bld.id)"
>     )
> 
> 
> class Br(Base):
>     __tablename__ = "tb_br"
>     __bind_key__ = "testdb"
>     __table_args__ = (
>         {
>             "mysql_engine": "InnoDB",
>             "mysql_charset": "utf8",
>             "mysql_collate": "utf8_general_ci",
>         },
>     )
> 
>     id = db.Column("id", db.Integer, primary_key=True, autoincrement=True)
>     name = db.Column("name", db.String(45), nullable=False)
> 
> 
> class Bld(Base):
>     __tablename__ = "tb_bld"
>     __bind_key__ = "testdb"
>     __table_args__ = (
>         {
>             "mysql_engine": "InnoDB",
>             "mysql_charset": "utf8",
>             "mysql_collate": "utf8_general_ci",
>         },
>     )
> 
>     id = db.Column("id", db.Integer, primary_key=True, autoincrement=True)
> 
>     name = db.Column("name", db.String(100), nullable=False)
> 
>     variant_id = db.Column(
>         "variant_id",
>         db.Integer,
>         db.ForeignKey(
>             "tb_nv.id",
>             name="fk_tb_bld_variant_id",
>             onupdate="CASCADE",
>             ondelete="RESTRICT",
>         ),
>         nullable=False,
>     )
> 
>     variant = db.relationship("NV")
> 
> 
> def display(values):
>     """Display values in a decent way."""
>     pprint.pprint(values)
> 
> 
> def connect():
>     """
>     Connect to Staging for testing.
> 
>     This is based on 
> https://medium.com/analytics-vidhya/translating-sql-queries-to-sqlalchemy-orm-a8603085762b
>     ...and ./game-publishing/services/api/deploy/celery/config/staging-base.j2
>     """
>     conn_str = "mysql://{}:{}@{}/{}".format(
>         os.environ["DBU"],
>         os.environ["DBP"],
>         os.environ["DBH"],
>         os.environ["IDB"],
>     )
>     engine = create_engine(conn_str)
> 
>     # Added 2023-03-17
>     Base.metadata.create_all(engine)
> 
>     session = sessionmaker(bind=engine)
>     sess = session()
>     return (engine, sess)
> 
> 
> def main():
>     """A minimal query that exhibits the problem."""
>     (engine, session) = connect()
> 
>     Base.metadata.create_all(engine)
> 
>     v_2 = aliased(Vers, name="v_2")
>     bs = aliased(St, name="bs")
>     bs_2 = aliased(St, name="bs_2")
>     bs_3 = aliased(St, name="bs_3")
> 
>     # sqlalchemy.exc.OperationalError: (MySQLdb.OperationalError) (1054, 
> "Unknown column 'tb_br.id' in 'on clause'")
>     # [SQL: SELECT tb_nv.id, min(bs_3.build_id) AS min_1
>     # FROM tb_nv, tb_brst AS bs_3, tb_brst AS bs
>     # INNER JOIN tb_vers AS v_2 ON bs.version_id = v_2.id
>     # INNER JOIN tb_brst AS bs_2 ON tb_br.id = bs_2.branch_id]
>     query = (
>         select(NV.id, func.min(bs_3.build_id))
>         .select_from(bs)
>         .join(v_2, onclause=(bs.version_id == v_2.id))
>         .join(bs_2, onclause=(Br.id == bs_2.branch_id))
>     )
>     result = session.execute(query)
> 
>     display(result.scalar().all())
> 
> 
> main()
> 
> 
> I'm using:
> $ python3 -m pip list -v | grep -i sqlalchemy
> Flask-SQLAlchemy 2.5.1 
> /data/home/dstromberg/.local/lib/python3.10/site-packages pip SQLAlchemy 
> 1.4.36 /data/home/dstromberg/.local/lib/python3.10/site-packages pip $ 
> python3 -m pip list -v | grep -i mysql mysqlclient 2.1.1 
> /data/home/dstromberg/.local/lib/python3.10/site-packages pip PyMySQL 0.8.0 
> /data/home/dstromberg/.local/lib/python3.10/site-packages pip bash-4.2# mysql 
> --version mysql Ver 14.14 Distrib 5.7.41, for Linux (x86_64) using EditLine 
> wrapper
> 
> 
> Any hints?
> 
> Thanks!
> 
> 
> 
> -- 
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/
>  
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/1576c1a1-e108-4bb0-83eb-57ab4125c457n%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/1576c1a1-e108-4bb0-83eb-57ab4125c457n%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/1896c52f-a997-4bbc-b78f-47a13077e797%40app.fastmail.com.

Reply via email to