vendredi 26 février 2016

SQLAlchemy joining with foreign key - empty query results

I am trying to join tables using SQLAlchemy that were previously produced by using pandas to_sql functionality. Here is an example setup:

from sqlalchemy import Column, Integer, Text, ForeignKey, MetaData
from sqlalchemy import create_engine
import migrate.changeset
import pandas as pd

# generate example tables from pandas
engine = create_engine('sqlite:///test.db')
parent_name = 'phil'
child_name = 'mary'
df_parent = pd.DataFrame.from_dict({1: {'colA': 1, 'colB': 2}}).transpose()
df_child = pd.DataFrame.from_dict({1: {'colC': 1}}).transpose()
df_parent.to_sql(parent_name, engine, index_label='id')
df_child.to_sql(child_name, engine, index_label='id')

# pandas does not produce a foreign key constraint, so add it
meta = MetaData(bind=engine)
meta.reflect()
col = Column('mapping', Text, ForeignKey('{}.id'.format(parent_name)))
col.create(meta.tables[child_name])

In this, I produce the tables, then alter them to have a ForeignKey mapping the child to the parent. Now, in a later query session, I produce models for these tables and attempt to join them:

# now we are in a later instance, and we want to query the join of phil and mary
from sqlalchemy import Column, Integer, Text, ForeignKey, MetaData
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///test.db', echo=True)
parent_name = 'phil'
child_name = 'mary'
meta = MetaData(bind=engine)
Base = declarative_base(metadata=meta)

# create (dynamically named) models for this database
parent_dict = {'id': Column(Text, primary_key=True), '__tablename__': parent_name,
               'colA': Column(Integer), 'colB': Column(Integer)}
child_dict = {'id': Column(Text, primary_key=True), '__tablename__': child_name,
              'mapping': Column(Text, ForeignKey('{}.id'.format(parent_name))),
              'colC': Column(Integer)}

my_parent = type('parent', (Base,), parent_dict)
my_child = type('child', (Base,), child_dict)

Session = sessionmaker(bind=engine)
session = Session()

session.query(my_parent).join(my_child).all()

And this gives the result:

>>> session.query(my_parent).join(my_child).all()
2016-02-26 18:14:08,575 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
2016-02-26 18:14:08,576 INFO sqlalchemy.engine.base.Engine ()
2016-02-26 18:14:08,576 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
2016-02-26 18:14:08,576 INFO sqlalchemy.engine.base.Engine ()
2016-02-26 18:14:08,578 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2016-02-26 18:14:08,579 INFO sqlalchemy.engine.base.Engine SELECT phil.id AS phil_id, phil."colA" AS "phil_colA", phil."colB" AS "phil_colB"
FROM phil JOIN mary ON phil.id = mary.mapping
2016-02-26 18:14:08,580 INFO sqlalchemy.engine.base.Engine ()
[]

Why is the result empty? What is wrong with my foreign key constraint? I can tell that

Aucun commentaire:

Enregistrer un commentaire