Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding @declared_attr __tablename__ to Mixin is overridden by _BoundDeclarativeMeta #323

Closed
mike-hart opened this issue Jul 2, 2015 · 3 comments
Assignees
Milestone

Comments

@mike-hart
Copy link

Using 2.0

I was using a mixin on my models to add a __tablename__ method to work out a prefixed/namespaced table name based on the class name but _BoundDeclarativeMeta's doesn't appear to check against base classes before adding its own.

This lead to errors like:
NoReferencedTableError: Foreign key associated with column 'not_yet_built.dependent_thoroughfare_id' could not find table 'paf_thoroughfare' with which to generate a foreign key to target column 'thoroughfare_id'

class PAFMixin(object):

    @declared_attr
    def __tablename__(cls):
        return 'paf' + re.sub(
            '[A-Z]', lambda match: '_' + match.group(0).lower(), cls.__name__)

Note that the class would prefix the table-name with paf, but this was not present in the first name of the exception (the latter is the reference from the ForeignKey itself). This prevents namespacing on systems that don't support schema (MySQL) and could be very confusing for others.

@davidism
Copy link
Member

davidism commented Jul 2, 2015

Would you produce a full test case for this? Also, ensure that you are using the latest version of SQLAlchemy 1.0, 0.9, or 0.8 branches, and specify which you're using.

@mike-hart
Copy link
Author

import re

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy import (Column, ForeignKey, Integer)
from sqlalchemy.ext.declarative import declared_attr


app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
db = SQLAlchemy(app)


class PAFMixin(object):

    @declared_attr
    def __tablename__(cls):
        return 'paf' + re.sub(
            '[A-Z]', lambda match: '_' + match.group(0).lower(), cls.__name__)


class Locality(PAFMixin, db.Model):

    locality_id = Column(Integer, primary_key=True)


class Address(PAFMixin, db.Model):

    address_id = Column(Integer, primary_key=True)
    locality_id = Column(Integer, ForeignKey('paf_locality.locality_id'))


db.create_all()

Results in:
sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'address.locality_id' could not find table 'paf_locality' with which to generate a foreign key to target column 'locality_id'

$ pip freeze | grep Alc
Flask-SQLAlchemy==2.0
SQLAlchemy==1.0.6

Hopefully this is sufficient information?

@paxswill
Copy link

I also encountered this, and have a pair of test cases (909bb21)in my mixin-tablenames branch. The second commit (19fc6ab) resolves the test cases, but it feels like a really hacky solution.

@davidism davidism self-assigned this Jul 14, 2016
@davidism davidism modified the milestone: v2.2 Jan 15, 2017
eve-n0rman added a commit to eve-n0rman/evesrp that referenced this issue Oct 29, 2018
Flask-SQLAlchemy was overriding __tablename__ set in mixins.  Upgrading to more recent version should also fix, but would require more re-work due to other changes.

pallets-eco/flask-sqlalchemy#323
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

3 participants