Automapping certain sqlalchemy indexes produces duplicate representation

Issue #3861 resolved
RobS created an issue

I'm not really sure what's going on here but for this particular schema after reflection via the automapper the indexes are duplicated. If you remove anything from the table definitions the duplication goes away.

$ cat repro.sql 
CREATE TABLE "users" ("id" integer not null primary key autoincrement not null, "slug" varchar(150) not null, "email" varchar(254) not null);
CREATE UNIQUE INDEX users_email_unique on "users" ("email");
CREATE TABLE "refreshtokens" ("id" integer not null primary key autoincrement, "user_id" integer not null, foreign key("user_id") references "users"("id"));
CREATE UNIQUE INDEX users_slug_unique on "users" ("slug");

$ sqlite3 repro.db ".read repro.sql"

$ cat repro.py 
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine

Base = automap_base()
engine = create_engine("sqlite:///repro.db")
Base.prepare(engine, reflect=True)
users = Base.metadata.tables.get('users')
print(users.indexes)

$ python repro.py
set([Index('users_slug_unique', Column('slug', VARCHAR(length=150), table=<users>, nullable=False), unique=True), Index('users_email_unique', Column('email', VARCHAR(length=254), table=<users>, nullable=False), unique=True), Index('users_email_unique', Column('email', VARCHAR(length=254), table=<users>, nullable=False), unique=True), Index('users_slug_unique', Column('slug', VARCHAR(length=150), table=<users>, nullable=False), unique=True)])

$ pip freeze
PyMySQL==0.7.9
SQLAlchemy==1.1.4

$ python --version
Python 2.7.9

$ sqlite3 --version
3.8.7.1 2014-10-29 13:59:56 3b7b72c4685aa5cf5e675c2c47ebec10d9704221

Comments (2)

  1. Mike Bayer repo owner

    Add _extend_on deduplicating set for metadata.reflect()

    The "extend_existing" option of :class:.Table reflection would cause indexes and constraints to be doubled up in the case that the parameter were used with :meth:.MetaData.reflect (as the automap extension does) due to tables being reflected both within the foreign key path as well as directly. A new de-duplicating set is passed through within the :meth:.MetaData.reflect sequence to prevent double reflection in this way.

    Change-Id: Ibf6650c1e76a44ccbe15765fd79df2fa53d6bac7 Fixes: #3861

    → <<cset 55ad10370f9e>>

  2. Log in to comment