来自Django,我很难搞清楚多对多关系的运作方式。
以下models.py不起作用,我收到错误: InvalidRequestError:一个或多个映射器无法初始化 - 无法继续初始化其他映射器。最初的例外是:在关系'Sector.companies'上创建backref'扇区'时出错:映射器'Mapper |公司|公司'
上存在该名称的属性代码如下:
`
company_contacts = db.Table('company_contacts',
db.Column('company_id', db.Integer, db.ForeignKey('companies.id')),
db.Column('contact_id', db.Integer, db.ForeignKey('contacts.id'))
)
company_sectors = db.Table('company_sectors',
db.Column('company_id', db.Integer, db.ForeignKey('companies.id')),
db.Column('sector_id', db.Integer, db.ForeignKey('sectors.id'))
)
company_worklists = db.Table('company_worklists',
db.Column('company_id', db.Integer, db.ForeignKey('companies.id')),
db.Column('worklist_id', db.Integer, db.ForeignKey('worklists.id'))
)
class Sector(db.Model):
__tablename__ = 'sectors'
id = db.Column(db.Integer, primary_key = True)
name_srb= db.Column(db.String(64), unique = True)
name_ita= db.Column(db.String(64), unique = True)
companies = db.relationship('Company',
secondary = company_sectors,
backref = db.backref('sectors', lazy = 'dynamic'),
lazy = 'dynamic')
class Contact(db.Model):
__tablename__ = 'contacts'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(64), unique = False)
last_name = db.Column(db.String(64), unique = False)
position_srb = db.Column(db.String(64), unique = False)
position_ita = db.Column(db.String(64), unique = False)
email = db.Column(db.String(120), unique = True)
phone = db.Column(db.String(100))
created = db.Column(db.DateTime(), default=datetime.now)
updated = db.Column(db.DateTime(), default=datetime.now,onupdate=datetime.now)
#companies = db.relationship('Company',
#secondary = company_contacts,
#backref = db.backref('companies', lazy = 'dynamic'),
#lazy = 'dynamic')
class WorkList(db.Model):
__tablename__ = 'worklists'
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(64), unique = True)
created = db.Column(db.DateTime(), default = datetime.now)
updated = db.Column(db.DateTime(), default=datetime.now,onupdate=datetime.now)
slug = db.Column(db.String(100), unique = True)
class Company(db.Model):
__tablename__ = 'companies'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(64), unique = True)
address = db.Column(db.String(120), unique = False)
website = db.Column(db.String(100), unique = False)
city = db.Column(db.String(20), unique = False)
desc = db.Column(db.Text())
email = db.Column(db.String(120), unique = True)
created = db.Column(db.DateTime(), default=datetime.now)
updated = db.Column(db.DateTime(), default=datetime.now,onupdate=datetime.now)
slug = db.Column(db.String(100), unique = True)
phone = db.Column(db.String(100))
fax = db.Column(db.String(100), unique = False)
contacts = db.relationship('Contact',
secondary = company_contacts,
backref = db.backref('contacts', lazy = 'dynamic'),
lazy = 'dynamic')
sectors = db.relationship('Sector',
secondary = company_sectors,
backref = db.backref('sectors', lazy = 'dynamic'),
lazy = 'dynamic')
wlists= db.relationship('WorkList',
secondary = company_worklists,
backref = db.backref('wlists', lazy = 'dynamic'),
lazy = 'dynamic')
我希望能够访问Company.contacts和Contact.companies之类的东西...... `'
答案 0 :(得分:4)
relationship(backref=...)
构造是一种方便的机制,因此您可以获得指向两个方向的引用,Company.sectors
和Sector.companies
只定义了一个。您已定义了两种关系。你似乎已经想到了这一点;你的代码中包含许多将以注释掉的形式重复引用。
删除所有重复的关系(你已经定义了相应的backref),你应该没问题。
或者,您可以使用relationship(back_populates=...)
构造并明确定义所有版权。这样,你可以在每个类上看到它在类本身上有什么样的集合属性,但是它们将被正确地绑在一起。
答案 1 :(得分:1)
IfLoop的答案是正确的,但您还应该将元数据参数包含在关联表的定义中。我修改了你的例子让它运行:
#!/bin/python
from datetime import datetime
from sqlalchemy import Table
from sqlalchemy import Integer, Text, String, ForeignKey, create_engine, Column, PrimaryKeyConstraint, DateTime
from sqlalchemy.orm import relationship, backref, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///:memory:', echo=True)
Base = declarative_base()
company_contacts = Table('company_contacts', Base.metadata, Column('company_id', Integer, ForeignKey('companies.id')), Column('contact_id', Integer, ForeignKey('contacts.id')) )
company_sectors = Table('company_sectors',
Base.metadata,
Column('company_id', Integer, ForeignKey('companies.id')),
Column('sector_id', Integer, ForeignKey('sectors.id'))
)
company_worklists = Table('company_worklists',
Base.metadata,
Column('company_id', Integer, ForeignKey('companies.id')),
Column('worklist_id', Integer, ForeignKey('worklists.id'))
)
class Sector(Base):
__tablename__ = 'sectors'
id = Column(Integer, primary_key = True)
name_srb= Column(String(64), unique = True)
name_ita= Column(String(64), unique = True)
class Contact(Base):
__tablename__ = 'contacts'
id = Column(Integer, primary_key = True)
name = Column(String(64), unique = False)
last_name = Column(String(64), unique = False)
position_srb = Column(String(64), unique = False)
position_ita = Column(String(64), unique = False)
email = Column(String(120), unique = True)
phone = Column(String(100))
created = Column(DateTime(), default=datetime.now)
updated = Column(DateTime(), default=datetime.now,onupdate=datetime.now)
#companies = relationship('Company',
#secondary = company_contacts,
#backref = backref('companies', lazy = 'dynamic'),
#lazy = 'dynamic')
class WorkList(Base):
__tablename__ = 'worklists'
id = Column(Integer, primary_key = True)
title = Column(String(64), unique = True)
created = Column(DateTime(), default = datetime.now)
updated = Column(DateTime(), default=datetime.now,onupdate=datetime.now)
slug = Column(String(100), unique = True)
class Company(Base):
__tablename__ = 'companies'
id = Column(Integer, primary_key = True)
name = Column(String(64), unique = True)
address = Column(String(120), unique = False)
website = Column(String(100), unique = False)
city = Column(String(20), unique = False)
desc = Column(Text())
email = Column(String(120), unique = True)
created = Column(DateTime(), default=datetime.now)
updated = Column(DateTime(), default=datetime.now,onupdate=datetime.now)
slug = Column(String(100), unique = True)
phone = Column(String(100))
fax = Column(String(100), unique = False)
contacts = relationship('Contact',
secondary = company_contacts,
backref = backref('contacts', lazy = 'dynamic'),
lazy = 'dynamic')
sectors = relationship('Sector',
secondary = company_sectors,
backref = backref('companies', lazy = 'dynamic'),
lazy = 'dynamic')
wlists= relationship('WorkList',
secondary = company_worklists,
backref = backref('wlists', lazy = 'dynamic'),
lazy = 'dynamic')
Base.metadata.create_all(engine)
session = sessionmaker(bind=engine)()
company = Company(name="C1")
session.add(company)
contact = Contact(last_name="Doe", name="John")
company.contacts.append(contact)
请问你在哪里得到了" db。"约定来自?最近还有一个问题,即元数据参数也缺失:Query many-to-many in SQLAlchemy