Sqlalchemy会自动为外键创建索引吗?

3

我在MYSQL中使用MyISAM引擎。我发现表中的外键已经自动创建了索引。这是Sqlalchemy或MYSQL的行为吗?我不需要外键的索引。我该怎么办?在定义列时添加参数index=False吗?

我的代码:

class A(Base):
    __tablename__ = "a"
    a_id = Column(BigInteger, primary_key=True, autoincrement=True)

class B(Base):
    __tablename__ = "b"
    b_id = Column(BigInteger, primary_key=True, autoincrement=True)
    a_id = Column(BigInteger, ForeignKey(A.a_id))

我发现 B 表中 a_id 的索引已经自动创建了,这样做是否正确? 如果我想删除这样的索引,该怎么办?

class B(Base):
    __tablename__ = "b"
    b_id = Column(BigInteger, primary_key=True, autoincrement=True)
    a_id = Column(BigInteger, ForeignKey(A.a_id), index=False)

请提供创建MyISAM索引的代码。 - Nilesh
如果某个物品上没有索引,就不能在该物品上有外键... - ceejayoz
3个回答

2

1

我在本地机器上创建了您的模型,但是没有找到任何外键索引。

我使用

from sqlalchemy import create_engine

engine = create_engine('mysql://test:test@localhost/test1', echo=True)

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Date, Text, BigInteger, ForeignKey
from sqlalchemy.orm.attributes import InstrumentedAttribute


Base = declarative_base()


class A(Base):
    __tablename__ = "a"
    a_id = Column(BigInteger, primary_key=True, autoincrement=True)

class B(Base):
    __tablename__ = "b"
    b_id = Column(BigInteger, primary_key=True, autoincrement=True)
    a_id = Column(BigInteger, ForeignKey(A.a_id))

Base.metadata.create_all(engine)

而且背景日志是。

2012-02-24 09:39:24,249 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2012-02-24 09:39:24,249 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,254 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'character_set%%'
2012-02-24 09:39:24,254 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,277 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'lower_case_table_names'
2012-02-24 09:39:24,277 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,288 INFO sqlalchemy.engine.base.Engine SHOW COLLATION
2012-02-24 09:39:24,289 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,292 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2012-02-24 09:39:24,292 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,293 INFO sqlalchemy.engine.base.Engine DESCRIBE `a`
2012-02-24 09:39:24,293 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,321 INFO sqlalchemy.engine.base.Engine ROLLBACK
2012-02-24 09:39:24,322 INFO sqlalchemy.engine.base.Engine DESCRIBE `b`
2012-02-24 09:39:24,322 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,323 INFO sqlalchemy.engine.base.Engine ROLLBACK
2012-02-24 09:39:24,324 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE a (
    a_id BIGINT NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (a_id)
)


2012-02-24 09:39:24,324 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,590 INFO sqlalchemy.engine.base.Engine COMMIT
2012-02-24 09:39:24,591 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE b (
    b_id BIGINT NOT NULL AUTO_INCREMENT, 
    a_id BIGINT, 
    PRIMARY KEY (b_id), 
    FOREIGN KEY(a_id) REFERENCES a (a_id)
)


2012-02-24 09:39:24,591 INFO sqlalchemy.engine.base.Engine ()
2012-02-24 09:39:24,762 INFO sqlalchemy.engine.base.Engine COMMIT

我还检查了mysql中ab的创建表语句。

mysql> show create table a;
+-------+-------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                  |
+-------+-------------------------------------------------------------------------------------------------------------------------------+
| a     | CREATE TABLE `a` (
  `a_id` bigint(20) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`a_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show create table b;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| b     | CREATE TABLE `b` (
  `b_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `a_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`b_id`),
  KEY `a_id` (`a_id`),
  CONSTRAINT `b_ibfk_1` FOREIGN KEY (`a_id`) REFERENCES `a` (`a_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

索引仅适用于主键而非外键。

请在您的计算机上尝试此操作,如果发现您的计算机正在为表b中的外键创建索引,则请发布该日志和模型,就像我在这个答案中所写的一样。

希望这能解决您的问题。


谢谢。我会再试一次。顺便说一下,我使用的是MyISAM,而你使用的是InnoDB。不管怎样,我可以自己做。非常感谢! - flypen
如果您在MyISAM中获取索引,请提供日志。这将有助于我们了解MyISAM与InnoDB不同的行为。 - Nilesh

0

这是MySQL的行为,对于MySQL来说它是正确的。你应该接受这个事实。我至少不知道如何除去外键的索引。

在定义列时添加参数 index=False?

嗯,也许......我会试一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接