Hi,I've been using SQLAlchemy for the last couple of weeks. I'll definitely call myself a beginner so I apologize if I'm missing something obvious with this question :)
I'm working with a database where there is data split across tables with the exact same structure, so there are cases where I need to query more than one table and filter by the same criteria.
Looking around in the documentation I read about Concrete Table Inheritance and thought that could help me in this case.
And perform a query such as:session.query(Employee).filter(Employee.name=='test')It will apply the name filter after the union is done:SELECT pjoin.employee_id AS pjoin_employee_id, pjoin.name AS pjoin_name, pjoin.type AS pjoin_type, pjoin.manager_data AS pjoin_manager_data, pjoin.engineer_info AS pjoin_engineer_infoFROM (SELECT employees.employee_id AS employee_id, employees.name AS name, CAST(NULL AS VARCHAR(50)) AS manager_data, CAST(NULL AS VARCHAR(50)) AS engineer_info, 'employee' AS typeFROM employees UNION ALL SELECT managers.employee_id AS employee_id, managers.name AS name, managers.manager_data AS manager_data, CAST(NULL AS VARCHAR(50)) AS engineer_info, 'manager' AS typeFROM managers UNION ALL SELECT engineers.employee_id AS employee_id, engineers.name AS name, CAST(NULL AS VARCHAR(50)) AS manager_data, engineers.engineer_info AS engineer_info, 'engineer' AS typeFROM engineers) AS pjoinWHERE pjoin.name = :name_1Is there a way to ask SQLAlchemy to apply the filter to each table in the inner queries? They all have a name column, and in the case of a large dataset it's helpful because it avoids loading all the rows for each table first and then applying the WHERE clause.
Thanks for the valuable suggestions. You are actually correct: the scheme that they are using is sharding across tables, that's why the structure is the same.And the way I was setting things up is very similar to the example you mentioned (http://www.sqlalchemy.org/trac/wiki/UsageRecipes/EntityName) so that I could query multiple table names using the same class. I put together a small example that using that and a simplified version of Manager and Engineer. Constructing the union the way you suggested works (the criterion goes in the subquery's WHERE clause instead of outside of the union).SELECT anon_1.manager_employee_id AS anon_1_manager_employee_id, anon_1.manager_name AS anon_1_manager_nameFROM (SELECT manager.employee_id AS manager_employee_id, manager.name AS manager_nameFROM managerWHERE manager.name = :name_1 UNION ALL SELECT engineer.employee_id AS engineer_employee_id, engineer.name AS engineer_nameFROM engineerWHERE engineer.name = :name_2) AS anon_1But now the problem seems to be that SQLAlchemy will only return rows matching the first class.Here's the example code. In this case there is 1 row in the manager & engineer tables that contains the name "test". After constructing the union, I was hoping the query would return two results but it will only return one. However if I run count() on the query, it correctly states that there are two rows. Am I missing something else?