SQLAlchemy:从外键推断出的列类型

时间:2019-04-30 05:01:52

标签: python sqlalchemy

我定义了一个多对多关联表...

derived_prime_sport_stats = Table(
    'derived_prime_sport_stats',
    Base.metadata,
    Column(
        'prime_sport_id',
        ForeignKey('prime_sports.id', ondelete='RESTRICT'),
        primary_key=True
    ),
    Column(
        'stat_record_id',
        ForeignKey('stat_record.id', ondelete='CASCADE'),
        primary_key=True
    )
)

...进行了迁移并继续前进。

后来,我意识到我忘了将type_参数传递给Table中每一列的构造函数,我以为迁移一定会失败。

但是,mysql> show create table derived_prime_sport_stats;显示:

CREATE TABLE `derived_prime_sport_stats` (
  `prime_sport_id` smallint(5) unsigned NOT NULL,
  `stat_record_id` bigint(20) unsigned NOT NULL,
  PRIMARY KEY (`prime_sport_id`,`stat_record_id`),
  KEY `fk_derived_prime_sport_stats_stat_record_id_stat_record` (`stat_record_id`),
  CONSTRAINT `fk_derived_prime_sport_stats_prime_sport_id_prime_sports` FOREIGN KEY (`prime_sport_id`) REFERENCES `prime_sports` (`id`),
  CONSTRAINT `fk_derived_prime_sport_stats_stat_record_id_stat_record` FOREIGN KEY (`stat_record_id`) REFERENCES `stat_record` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci 

...类型已根据相关列的类型进行配置,而未明确指定。

已记录了此行为,但是我无法找到有关stackoverflow的相关问题,因此我将其作为参考,因为我认为许多主要通过ORM与SQLAlchemy进行交互的人可能并不了解该功能。

1 个答案:

答案 0 :(得分:0)

documentation for the type_ arg to Column指定:

  

如果类型为None或被省略,它将首先默认为   特殊类型NullType。是否以及何时引用本专栏   另一列使用ForeignKey和/或ForeignKeyConstraint,类型   远程引用列的也会被复制到该列,   在针对该遥控器解析外键的那一刻   列对象。

ForeignKey的父列附加到其表时,将调用ForeignKey._set_table()方法,在该方法中,FK解析其引用的外部表的列。此时,如果FK的父列没有类型,它将从外部列进行设置。发生在ForeignKey._set_target_column()中的here

# propagate TypeEngine to parent if it didn't have one
if self.parent.type._isnull:
    self.parent.type = column.type

有趣的是,在the expression language tutorial中定义表的第一个示例中:

>>> from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
>>> metadata = MetaData()
>>> users = Table('users', metadata,
...     Column('id', Integer, primary_key=True),
...     Column('name', String),
...     Column('fullname', String),
... )

>>> addresses = Table('addresses', metadata,
...   Column('id', Integer, primary_key=True),
...   Column('user_id', None, ForeignKey('users.id')),
...   Column('email_address', String, nullable=False)
...  )

... addresses.user_id列的类型已显式设置为None以利用此功能,但是直到{{1}的API参考之前,似乎没有任何解释。 }。