SQLAlchemy changing table name to have two underscores

Question:

In my Flask/SQLAlchemy project, I have an index table called Styles_Index, which has a corresponding table object that I query on.
The schema in sqlite3 looks like

CREATE TABLE Styles_Index
(
    beer_id integer not null, 
    style_id integer not null, 
    primary key (beer_id, style_id)
);

And the object in python looks like

class Styles_Index(db.Model):
    beer_id = db.Column(db.Integer, db.ForeignKey('beers.id'),
            primary_key = True)
    style_id = db.Column(db.Integer, db.ForeignKey('styles.id'),
            primary_key = True)

When I try to join the table onto another that shares a common key via the SQLAlchemy BaseQuery.join(), it creates a query:

SELECT styles__index.id AS styles__index_id, 
    styles__index.beer_id AS styles__index_beer_id, 
    styles__index.style_id AS styles__index_style_id
    FROM styles__index JOIN styles ON styles__index.style_id = styles.id
    LIMIT ? OFFSET ?

where Styles_Index has two underscores instead of one.
Is this an intentional design choice due to the _ wildcard character in SQL? Is there a better way to write this query, without resorting to writing raw SQL?

Asked By: N W

||

Answers:

For the record, using PEP 8 specific names such as MyClassName, will not have such an issue.

Answered By: Mitchell Currie

Flask-SQLAlchemy will automatically generate a table name from the model class name if neither __tablename__ nor __table__ are defined on the model class.

The generation function (camel_to_snake_case) uses a regular expression substitution (link) which inserts an underscore before some internal uppercase letters and then downcases the result. Thus a class name with an underscore before an internal uppercase letter results in a name containing a double-underscore.

Answered By: snakecharmerb