Adding a join to an SQL Alchemy expression that already has a select_from()

2024/9/28 9:32:17

Note: this is a question about SQL Alchemy's expression language not the ORM

SQL Alchemy is fine for adding WHERE or HAVING clauses to an existing query:

q = select([bmt_gene.c.id]).select_from(bmt_gene)
q = q.where(bmt_gene.c.ensembl_id == "ENSG00000000457")
print q
SELECT bmt_gene.id 
FROM bmt_gene 
WHERE bmt_gene.ensembl_id = %s

However if you try to add a JOIN in the same way you'll get an exception:

q = select([bmt_gene.c.id]).select_from(bmt_gene)
q = q.join(bmt_gene_name)

sqlalchemy.exc.NoForeignKeysError: Can't find any foreign key relationships between 'Select object' and 'bmt_gene_name'


If you specify the columns it creates a subquery (which is incomplete SQL anyway):

q = select([bmt_gene.c.id]).select_from(bmt_gene)
q = q.join(bmt_gene_name, q.c.id == bmt_gene_name.c.gene_id)
(SELECT bmt_gene.id AS id FROM bmt_gene)
JOIN bmt_gene_name ON id = bmt_gene_name.gene_id

But what I actually want is this:

SELECTbmt_gene.id AS id 
FROMbmt_geneJOIN bmt_gene_name ON id = bmt_gene_name.gene_id

edit: Adding the JOIN has to be after the creation of the initial query expression q. The idea is that I make a basic query skeleton then I iterate over all the joins requested by the user and add them to the query.

Can this be done in SQL Alchemy?

Answer

The first error (NoForeignKeysError) means that your table lacks foreign key definition. Fix this if you don't want to write join clauses by hand:

from sqlalchemy.types import Integer
from sqlalchemy.schema import MetaData, Table, Column, ForeignKeymeta = MetaData()bmt_gene_name = Table('bmt_gene_name', meta,Column('id', Integer, primary_key=True),Column('gene_id', Integer, ForeignKey('bmt_gene.id')),# ...
)

The joins in SQLAlchemy expression language work a little bit different from what you expect. You need to create Join object where you join all the tables and only then provide it to Select object:

q = select([bmt_gene.c.id])
q = q.where(bmt_gene.c.ensembl_id == 'ENSG00000000457')j = bmt_gene  # Initial table to join.
table_list = [bmt_gene_name, some_other_table, ...]
for table in table_list:j = j.join(table)
q = q.select_from(j)

The reason why you see the subquery in your join is that Select object is treated like a table (which essentially it is) which you asked to join to another table.

https://en.xdnf.cn/q/71350.html

Related Q&A

How should I move blobs from BlobStore over to Google Cloud Storage?

Our application has been running on App Engine using the Blobstore for years. We would like to move our video files over to Google Cloud Storage. What is the best practice for migrating large blobs f…

Python: Find `sys.argv` before the `sys` module is loaded

I want to find the command line arguments that my program was called with, i.e. sys.argv, but I want to do that before Python makes sys.argv available. This is because Im running code in usercustomize.…

Dotted lines instead of a missing value in matplotlib

I have an array of some data, where some of the values are missingy = np.array([np.NAN, 45, 23, np.NAN, 5, 14, 22, np.NAN, np.NAN, 18, 23])When I plot it, I have these NANs missing (which is expected)f…

How to change the creation date of file using python on a mac?

I need to update the creation time of a .mp4 file so that it will appear at the top of a list of media files sorted by creation date. I am able to easily update both the accessed and modified date of …

Classification tree in sklearn giving inconsistent answers

I am using a classification tree from sklearn and when I have the the model train twice using the same data, and predict with the same test data, I am getting different results. I tried reproducing on…

Modifying binary file with Python

i am trying to patch a hex file. i have two patch files (hex) named "patch 1" and "patch 2"the file to be patched is a 16 MB file named "file.bin".i have tried many differ…

python error : module object has no attribute AF_UNIX

this is my python code :if __name__ == __main__: import socket sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) sock.connect((0.0.0.0, 4000)) import time time.sleep(2) #sock.send(1)print …

How to speed up pandas string function?

I am using the pandas vectorized str.split() method to extract the first element returned from a split on "~". I also have also tried using df.apply() with a lambda and str.split() to produc…

sqlalchemy autoloaded orm persistence

We are using sqlalchemys autoload feature to do column mapping to prevent hardcoding in our code.class users(Base):__tablename__ = users__table_args__ = {autoload: True,mysql_engine: InnoDB,mysql_chars…

Data Normalization with tensorflow tf-transform

Im doing a neural network prediction with my own datasets using Tensorflow. The first I did was a model that works with a small dataset in my computer. After this, I changed the code a little bit in or…