SQLAlchemy加入外键 - 空查询结果

时间:2016-02-27 02:20:28

标签: python sqlite sqlalchemy

我正在尝试使用以前使用pandas to_sql功能生成的SQLAlchemy连接表。以下是一个示例设置:

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])

在此,我生成表,然后更改它们以使ForeignKey将子映射到父级。现在,在稍后的查询会话中,我为这些表生成模型并尝试加入它们:

# 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()

这给出了结果:

>>> 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 ()
[]

为什么结果为空?我的外键约束有什么问题?据我所知,问题是由于我如何定义约束,因为如果我添加nullable=False,它会在尝试进行迁移时崩溃:

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: mary.mapping [SQL: u'INSERT INTO mary (id ,"colC") SELECT id ,"colC" from migration_tmp']

0 个答案:

没有答案