agronholm/sqlacodegen

Missing many-to-many relationship

Closed this issue · 1 comments

Things to check first

  • I have searched the existing issues and didn't find my bug already reported there

  • I have checked that my bug is still present in the latest release

Sqlacodegen version

3.0.0rc5

SQLAlchemy version

2.0.31

RDBMS vendor

MySQL (or compatible)

What happened?

I generated the code using the standard options.

I got this : (shortened)

class Cards(Base):
    __tablename__ = "cards"
    id: Mapped[str] = mapped_column(CHAR(36), primary_key=True)
    ...

class Wallets(Base):
    __tablename__ = "wallets"
    id: Mapped[int] = mapped_column(INTEGER, primary_key=True)
   ...

t_wallets_cards = Table(
    "wallets_cards",
    Base.metadata,
    Column("wallet_id", INTEGER),
    Column("card_id", CHAR(36)),
    Column("priority", SmallInteger),
    Column("created_at", TIMESTAMP),
    Column("updated_at", TIMESTAMP),
    ForeignKeyConstraint(
        ["card_id"], ["cards.id"], name="wallets_cards_card_id_foreign"
    ),
    ForeignKeyConstraint(
        ["wallet_id"],
        ["wallets.id"],
        ondelete="CASCADE",
        name="wallets_cards_wallet_id_foreign",
    ),
    Index("wallets_cards_card_id_foreign", "card_id"),
    Index("wallets_cards_wallet_id_foreign", "wallet_id"),
)

I was expecting to get a many-to-many relationship in cards and wallets.

Database schema for reproducing the bug

CREATE TABLE `cards` (
  `id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

CREATE TABLE `wallets` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
) ENGINE=InnoDB AUTO_INCREMENT=526903 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

CREATE TABLE `wallets_cards` (
  `wallet_id` int unsigned DEFAULT NULL,
  `card_id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `priority` smallint DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  KEY `wallets_cards_wallet_id_foreign` (`wallet_id`),
  KEY `wallets_cards_card_id_foreign` (`card_id`),
  CONSTRAINT `wallets_cards_card_id_foreign` FOREIGN KEY (`card_id`) REFERENCES `cards` (`id`),
  CONSTRAINT `wallets_cards_wallet_id_foreign` FOREIGN KEY (`wallet_id`) REFERENCES `wallets` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

Given that wallets_cards has more than the foreign keys columns, this table is ineligible for being an association table for a M2M relationship. See the relevant section of the README on that.