Skip to content

InvalidRequestError: Table … is already defined for this MetaData instance (table inheritance on v2.2) #478

@homeworkprod

Description

@homeworkprod

On Flask-SQLAlchemy 2.2 (Flask 0.12, SQLAlchemy 1.1.6, Python 3.5.3) I the following traceback that does not occur with Flask-SQLAlchemy 2.1:

Traceback (most recent call last):
  File "application.py", line 19, in <module>
    class ChildA(Parent):
  File "/home/user/project/venv/lib/python3.5/site-packages/flask_sqlalchemy/__init__.py", line 602, in __init__
    DeclarativeMeta.__init__(self, name, bases, d)
  File "/home/user/project/venv/lib/python3.5/site-packages/sqlalchemy/ext/declarative/api.py", line 64, in __init__
    _as_declarative(cls, classname, cls.__dict__)
  File "/home/user/project/venv/lib/python3.5/site-packages/sqlalchemy/ext/declarative/base.py", line 88, in _as_declarative
    _MapperConfig.setup_mapping(cls, classname, dict_)
  File "/home/user/project/venv/lib/python3.5/site-packages/sqlalchemy/ext/declarative/base.py", line 103, in setup_mapping
    cfg_cls(cls_, classname, dict_)
  File "/home/user/project/venv/lib/python3.5/site-packages/sqlalchemy/ext/declarative/base.py", line 131, in __init__
    self._setup_table()
  File "/home/user/project/venv/lib/python3.5/site-packages/sqlalchemy/ext/declarative/base.py", line 395, in _setup_table
    **table_kw)
  File "/home/user/project/venv/lib/python3.5/site-packages/sqlalchemy/sql/schema.py", line 418, in __new__
    "existing Table object." % key)
sqlalchemy.exc.InvalidRequestError: Table 'items' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

Somewhat minimal code to reproduce:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy


db = SQLAlchemy()


class Parent(db.Model):
    __tablename__ = 'items'
    __mapper_args__ = {
        'polymorphic_identity': 'parent',
        'polymorphic_on': 'type',
    }

    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.Unicode(10), nullable=False)


class ChildA(Parent):
    __mapper_args__ = {
        'polymorphic_identity': 'child_a',
    }

    foo = db.Column(db.Integer)


class ChildB(Parent):
    __mapper_args__ = {
        'polymorphic_identity': 'child_b',
    }

    bar = db.Column(db.Integer)


app = Flask(__name__)
app.run()

Unless I've been doing that wrong the whole time and just got away with it by chance, I think this might be unintended behavior on Flask-SQLAlchemy's side.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions