我使用SQLAlchemy的声明性API为我的应用程序构建我的模型和表。
但是,由于错误Base.metadata.create_all(engine)
NoReferencedTableError: Foreign key associated with column 'org_prediction.company_id' could not find table 'organization' with which to generate a foreign key to target column 'id'
命令在我的数据库中构建新表
发生这种情况的原因是因为我试图为ForeignKey引用的类组织在models.py文件中不存在。所以,当我调用Base.metadata.create_all(engine)
时,SQLAlchemy会因为类组织在Base中不存在而窒息......
我已经尝试反映我的数据库,它将返回存在的Organization的表,但是在models.py文件中没有为它编写相应的Class。但是当我反映数据库表并尝试在组织之上创建我的新依赖类时,我得到一个错误:InvalidRequestError: Table 'user' is already defined for this MetaData instance. Specify 'extend_existing=True' to redefine options and columns on an existing Table object.
,这是因为反映的MetaData和我的models.py类用于用户重叠,以及SQLAlchemy不确定该怎么做。
但是我在哪里应用extend_existing = True?我没有Table对象来传递此参数。当我的models.py文件中不存在我的FK依赖表时,如何创建我的FK依赖表?或者我如何反映我现有的表,但只追加或更新数据库中尚不存在的类?
models.py
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
username = Column(String(50))
class OrgPrediction(Base):
__tablename__ = 'org_prediction'
id = Column(Integer, primary_key=True)
company_id = Column(String(255), ForeignKey('organization.id'), nullable=True)
prediction = Column(String(255)
Base.metadata.create_all(engine)
NoReferencedTableError:与列'org_prediction.company_id'关联的外键无法找到用于生成目标列'id'的外键的表'organization'
MYSQL:
mysql> desc organization;
+-----------------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+------------+------+-----+---------+-------+
| id | bigint(20) | YES | MUL | NULL | |
mysql> show tables;
+-------------------------+
| Tables_in_database |
+-------------------------+
| organization |
| user |
| user_email |
对于Reflection的models.py文件:
from sqlalchemy.ext.automap import automap_base
from sqlalchemy import create_engine
Base = automap_base()
Base.prepare(engine, reflect=True)
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
username = Column(String(50))
class OrgPrediction(Base):
__tablename__ = 'org_prediction'
id = Column(Integer, primary_key=True)
company_id = Column(String(255), ForeignKey('organization.id'), nullable=True)
Base.metadata.create_all(engine)
InvalidRequestError:已为此MetaData实例定义表'user'。指定'extend_existing = True'以重新定义现有Table对象上的选项和列。
答案 0 :(得分:0)
有一种方法可以做到这一点,它涉及在添加Foreign-Key-dependency表之前使用Base.metadata.reflect(only = [' table_name'])功能。我测试的最终代码:
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(Integer, primary_key=True)
username = Column(String(50))
#see what tables exist in metadata right now
In [85]: Base.metadata.sorted_tables
Out[85]: [Table('user', MetaData(bind=None), Column('id', Integer(), table=<user>, primary_key=True, nullable=False), Column('username', String(length=50), table=<user>), schema=None)]
# this will add the organization table/class to the Base's Metadata. This also needs to happen before the Foreign Key reference in OrgPrediction class.
Base.metadata.reflect(bind=engine, only=['organization'])
# now this class' foreign key will reference organization.id which exists in Base metadata.
class OrgPrediction(Base):
__tablename__ = 'org_prediction'
id = Column(Integer, primary_key=True)
company_id = Column(String(255), ForeignKey('organization.id'), nullable=True)
prediction = Column(String(255))
# this should pass because the foreign key constraint is met.
Base.metadata.create_all(engine)