[英]SQLAlchemy has maximum number of relationships?
I'm using python 3.6 and SQLAlchemy 1.3.8 and I'm facing an issue a little stranger...I'm receiving the same exception for multiple relationships (24 classes that relates to each other by many types of relationship) and the same issue happen exactly the same but with differ tables each time I run the script. 我正在使用python 3.6和SQLAlchemy 1.3.8,并且遇到了一个有点陌生的问题...我在多个关系(24个通过多种关系类型相互关联的类)中收到相同的异常每次运行脚本时,相同的问题完全相同,但表不同。 I wasn't facing it when the number of classes was less then twenty...so, is it possible that there's a maximum number of relationships?
当类的数量少于二十时,我并没有面对它……那么,有可能存在最大数量的关系吗?
The traceback is: 追溯为:
Traceback (most recent call last):
File "yaml_parser.py", line 70, in <module>
Base.metadata.create_all()
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/sql/schema.py", line 4294, in create_all
ddl.SchemaGenerator, self, checkfirst=checkfirst, tables=tables
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2046, in _run_visitor
conn._run_visitor(visitorcallable, element, **kwargs)
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1615, in _run_visitor
visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/sql/visitors.py", line 132, in traverse_single
return meth(obj, **kw)
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/sql/ddl.py", line 754, in visit_metadata
[t for t in tables if self._can_create_table(t)]
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/sql/ddl.py", line 1158, in sort_tables_and_constraints
dependent_on = fkc.referred_table
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/sql/schema.py", line 3218, in referred_table
return self.elements[0].column.table
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 855, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/home/jarvis/venv/lib/python3.6/site-packages/sqlalchemy/sql/schema.py", line 2025, in column
tablekey,
sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'model.<foreing_key_column>' could not find table '<table_name>' with which to generate a foreign key to target column 'id'
To reproduce, use the scripts bellow 要重现,请使用以下脚本
base.py base.py
#!/usr/bin/python3
import uuid
from sqlalchemy.dialects.mysql.base import MSBinary
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import String, Column, Integer, types
import re
def generate_uuid():
return str(uuid.uuid4())
def camel2snake(string):
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', string)
result = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
return result
class UUID(types.TypeDecorator):
impl = MSBinary
def __init__(self):
self.impl.length = 16
types.TypeDecorator.__init__(self, length=self.impl.length)
def process_bind_param(self, value, dialect=None):
if value and isinstance(value, uuid.UUID):
return value.bytes
elif value and not isinstance(value, uuid.UUID):
raise ValueError('value %s is not a valid uuid.UUID' % value)
else:
return None
def process_result_value(self, value, dialect=None):
if value:
return uuid.UUID(bytes=value)
else:
return None
def is_mutable(self):
return False
class NBase(object):
__tablename__ = camel2snake(__name__)
__table_args__ = {'extend_existing': True}
id = Column(UUID, primary_key=True, default=generate_uuid())
Base = declarative_base(cls=NBase)
class Timeframe(Base):
"""docstring for Timeframe"""
__tablename__ = camel2snake(__name__)
day = Column(Integer)
timestamp = Column(String)
model.py 模型
#!/usr/bin/python3
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, reconstructor
from sqlalchemy import (
Column, Integer, String, Boolean, ForeignKey, Enum, Text
)
from base import camel2snake, Base, Timeframe, UUID
class SliceObject(Base):
"""docstring for Slice"""
__tablename__ = camel2snake(__name__)
# One-to-one relationship with SliceConstraints class
slice_constraints = relationship(
"SliceConstraints", uselist=False,
back_populates="slice_object")
# One-to-one relationship with SliceRequirements class
slice_requirements = relationship(
"SliceRequirements", uselist=False,
back_populates="slice_object")
# One-to-one relationship with SliceLifecycle class
slice_lifecycle = relationship(
"SliceLifecycle", uselist=False, back_populates="slice_object")
# One-to-one relationship with SliceCost class
cost = relationship(
"SliceCost", uselist=False, back_populates="slice_object")
# One-to-one relationship with SliceTimeframe class
slice_timeframe = relationship(
"SliceTimeframe", uselist=False, back_populates="slice_object")
# One-to-many relationship with ServiceDescription class
service_description_id = Column(
UUID, ForeignKey(camel2snake("ServiceDescription") + ".id"))
service_description = relationship("ServiceDescription")
# One-to-many relationship with SliceDescription class
slice_description_id = Column(
UUID, ForeignKey(camel2snake("SliceDescription") + ".id"))
slice_description = relationship("SliceDescription")
class SliceConstraints(Base):
"""docstring for SliceConstraints"""
__tablename__ = camel2snake(__name__)
# One-to-one relationship with Geographic class
geographic = relationship(
"Geographic", uselist=False, back_populates="slice_constraints")
# One-to-one relationship with SliceObject class
slice_object_id = Column(UUID, ForeignKey(
camel2snake("SliceObject") + ".id"))
slice_object = relationship(
"SliceObject", back_populates="slice_constraints")
class Geographic(Base):
"""docstring for Geographic"""
__tablename__ = camel2snake(__name__)
# One-to-many relationship with Country enum
country = relationship("Country")
# One-to-one relationship with Geographic class
slice_constraints_id = Column(UUID, ForeignKey(
camel2snake("SliceConstraints") + ".id"))
slice_constraints = relationship(
"SliceConstraints", back_populates="geographic")
class Country(Base):
"""docstring for Country"""
__tablename__ = camel2snake(__name__)
# One-to-many relationship with Geographic class
geographic_id = Column(UUID, ForeignKey(
camel2snake("Geographic") + ".id"))
geographic = relationship("Geographic", back_populates="country")
class SliceRequirements(Base):
"""docstring for SliceRequirements"""
__tablename__ = camel2snake(__name__)
# One-to-one relationship with SliceObject class
slice_object_id = Column(UUID, ForeignKey(
camel2snake("SliceObject") + ".id"))
slice_object = relationship(
"SliceObject", back_populates="slice_requirements")
# One-to-many relationshipSliceTimeframe
reliability = relationship("Reliability")
class Reliability(Base):
"""docstring for Reliability"""
__tablename__ = camel2snake(__name__)
# One-to-many relationship
slice_requirements_id = Column(
UUID, ForeignKey(camel2snake("SliceRequirements") + ".id"))
slice_requirements = relationship(
"SliceRequirements", back_populates="reliability")
class SliceLifecycle(Base):
"""docstring for SliceLifecycle"""
__tablename__ = camel2snake(__name__)
# One-to-one relationship with SliceObject class
slice_object_id = Column(UUID, ForeignKey(
camel2snake("SliceObject") + ".id"))
slice_object = relationship(
"SliceObject", back_populates="slice_lifecycle")
class SliceCost(Base):
"""docstring for SliceCost"""
__tablename__ = camel2snake(__name__)
# One-to-one relationship with CostModel class
dc_model_id = Column(UUID, ForeignKey(
camel2snake("CostModel") + ".id"))
dc_model = relationship(
"CostModel", foreign_keys=[dc_model_id])
net_model_id = Column(UUID, ForeignKey(
camel2snake("CostModel") + ".id"))
net_model = relationship(
"CostModel", foreign_keys=[net_model_id]
)
# One-to-one relationship with SliceObject class
slice_object_id = Column(UUID, ForeignKey(
camel2snake("SliceObject") + ".id"))
slice_object = relationship(
"SliceObject", back_populates="cost")
class CostModel(Base):
"""docstring for CostModel"""
__tablename__ = camel2snake(__name__)
value_euros = relationship("CostValue")
class CostValue(Base):
"""docstring for CostValue"""
__tablename__ = camel2snake(__name__)
lower_than_equal = Column(Integer)
cost_model_id = Column(UUID, ForeignKey(
camel2snake("CostModel") + ".id"))
cost_model = relationship("CostModel", back_populates="value_euros")
class SliceTimeframe(Base):
"""docstring for SliceTimeframe"""
__tablename__ = camel2snake(__name__)
service_start_time_id = Column(
UUID, ForeignKey(camel2snake("Timeframe") + ".id"))
service_start_time = relationship(
"Timeframe", foreign_keys=[service_start_time_id])
service_stop_time_id = Column(
UUID, ForeignKey(camel2snake("Timeframe") + ".id"))
service_stop_time = relationship(
"Timeframe", foreign_keys=[service_stop_time_id])
# One-to-one relationship with SliceObject class
slice_object_id = Column(UUID, ForeignKey(
camel2snake("SliceObject") + ".id"))
slice_object = relationship(
"SliceObject", back_populates="slice_timeframe")
class ServiceDescription(Base):
"""docstring for ServiceDescription"""
__tablename__ = camel2snake(__name__)
# Many-to-one relationship with SliceObject class
slice_object = relationship(
"SliceObject", back_populates="service")
# One-to-many for ServiceFunction class
service_function_id = Column(UUID, ForeignKey(
camel2snake("ServiceFunction") + ".id"))
service_function = relationship("ServiceFunction")
# One-to-many for ServiceLink class
service_link_id = Column(UUID, ForeignKey(
camel2snake("ServiceLink") + ".id"))
service_link = relationship("ServiceLink")
class ServiceFunction(Base):
"""docstring for ServiceFunction"""
__tablename__ = camel2snake(__name__)
# Many-to-one relationship with SliceObject class
service_description = relationship(
"ServiceDescription", back_populates="service_function")
service_element_type = Column(String)
vdu = relationship(
"VDU", back_populates="service_function")
class VDU(Base):
"""docstring for VDU"""
__tablename__ = camel2snake(__name__)
service_function_id = Column(UUID, ForeignKey(
camel2snake("ServiceFunction") + ".id"))
service_function = relationship("ServiceFunction", back_populates="vdu")
# Many-to-one relationship with EPAAttributes class
epa_attr_id = Column(UUID, ForeignKey(
camel2snake("EPAAttributes") + ".id"))
epa_attr = relationship("EPAAttributes")
# Many-to-many relationship with VDUInterface class
vdu_interface_id = Column(UUID, ForeignKey(
camel2snake("VDUInterface") + '.id'))
vdu_interface = relationship("VDUInterface", back_populates="vdu")
class EPAAttributes(Base):
"""docstring for EPAAttributes"""
__tablename__ = camel2snake(__name__)
host_epa_id = Column(UUID, ForeignKey(
camel2snake("HostEPA") + ".id"))
host_epa = relationship("HostEPA")
hypervisor_epa = Column(UUID, ForeignKey(
camel2snake("HypervisorEPA") + '.id'))
hypervisor_epa = relationship("HypervisorEPA")
vim_epa_id = Column(UUID, ForeignKey(camel2snake("VIMEPA") + '.id'))
vim_epa = relationship("VIMEPA")
vswitch_epa_id = Column(UUID, ForeignKey(
camel2snake("VSwitchEPA") + '.id'))
vswitch_epa = relationship("VSwitchEPA")
class HostEPA(Base):
__tablename__ = camel2snake(__name__)
epa_attributes = relationship("EPAAttributes", back_populates='host_epa')
class HypervisorEPA(Base):
__tablename__ = camel2snake(__name__)
epa_attributes = relationship("EPAAttributes", back_populates='host_epa')
class VIMEPA(Base):
__tablename__ = camel2snake(__name__)
epa_attributes = relationship("EPAAttributes", back_populates='host_epa')
class VSwitchEPA(Base):
__tablename__ = camel2snake(__name__)
epa_attributes = relationship("EPAAttributes", back_populates='host_epa')
class VDUInterface(Base):
"""docstring for VDUInterface"""
__tablename__ = camel2snake(__name__)
vdu = relationship("VDU", back_populates='vdu_interface')
class ServiceLink(Base):
"""docstring for ServiceLink"""
__tablename__ = camel2snake(__name__)
# Many-to-one relationship with SliceObject class
service_description = relationship(
"ServiceDescription", back_populates="service_link")
service_element_type = Column(String)
link = relationship("Link", back_populates="service_link")
class Link(Base):
"""docstring for Link"""
__tablename__ = camel2snake(__name__)
service_link_id = Column(UUID, ForeignKey(
camel2snake("ServiceLink") + ".id"))
service_link = relationship("ServiceLink", back_populates="link")
class SliceDescription(Base):
"""docstring for SliceDescription"""
__tablename__ = camel2snake(__name__)
# Many-to-one relationship with SliceObject class
slice_object = relationship(
"SliceObject", back_populates="slice")
And run the python interpreter then the following: 并运行python解释器,然后执行以下操作:
>>> from model import SliceObject
>>> slice = SliceObject()
For the record, didn't found any similar error...so if you found some, please help :) 为了记录,没有发现任何类似的错误...所以,如果您发现了一些错误,请帮助:)
The problem was in the use of __name__
in __tablename__
attribute. 问题
__name__
在__tablename__
属性中使用__tablename__
。 __name__
refers to the name of the module not the name of the class. __name__
是指模块的名称,而不是类的名称。 For each class, substitute it for a string with the desired name (which I suppose is the class name). 对于每个类,将其替换为具有所需名称(我想是类名称)的字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.