Flask-SQLAlchemy很多很多

时间:2014-08-24 21:37:33

标签: python sqlalchemy flask-sqlalchemy

来自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之类的东西......     `'

2 个答案:

答案 0 :(得分:4)

relationship(backref=...)构造是一种方便的机制,因此您可以获得指向两个方向的引用,Company.sectorsSector.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