【问题标题】:Flask-SQLAlchemy Many-to-many relationship : How to insert dataFlask-SQLAlchemy 多对多关系:如何插入数据
【发布时间】:2020-03-23 05:13:15
【问题描述】:

我在我的 Flask-Sqlalchemy 模型中创建了多对多关系。但是,我似乎不太了解如何填充我的数据库。你能告诉我我应该如何编写代码来正确填充我的数据库吗?

这是我的模型:

company_contact = db.Table('company_contact', db.Model.metadata,
    db.Column('company_id', Integer, ForeignKey('company.id')),
    db.Column('contact_id', Integer, ForeignKey('contact.id'))
)

class Company(db.Model):
    __tablename__ = 'company'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    contacts = db.relationship('Contact', secondary=company_contact, back_populates="companies")
    company_name = db.Column(db.String(100))

    def __repr__(self):
        return '<Company {}{}>'.format(self.contacts, self.company_name)


class Contact(db.Model):
    __tablename__ = 'contact'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    last_name = db.Column(db.String(255))
    first_name = db.Column(db.String(255))
    job_position = db.Column(db.String(255))
    companies = db.relationship('Company', secondary=company_contact, back_populates="contacts")
    contact_status = db.Column(db.Enum('Client', 'Prospect', 'Churner', 'Prestataire', 'Reperage',
                                       name='contact_status'))
    start_date = db.Column(db.DateTime, server_default=db.func.now())
    stop_date = db.Column(db.DateTime, default=None)

    def __repr__(self):
        return '<Contact {}>'.format(self.last_name, self.first_name, self.job_position, self.companys,
                                     self.contact_status, self.start_date, self.stop_date)

我想要做的是添加两个具有相同公司名称的联系人。添加第一个不是问题,一切正常。但是,对于第二个联系人,当我添加此代码时会出现问题。

com = Company(company_name='bla')
con = Contact(last_name='Blabla', first_name='Jeff', job_position='Resp Marketing',contact_status='Client')
con.companies.append(com)
db.session.add(con)
db.session.commit()

sqlalchemy.exc.IntegrityError: (psycopg2.errors.UniqueViolation) 重复键值违反了唯一约束“company_company_name_key” 详细信息:键 (company_name)=(bla) 已存在。

我不知道如何写它来允许,两个联系人与同一家公司,也允许两个公司具有相同的联系人。

非常感谢您的帮助。

【问题讨论】:

    标签: python flask sqlalchemy many-to-many flask-sqlalchemy


    【解决方案1】:

    听起来您的数据库中已经有一个Company 和一个company_namebla。如果它已经存在,您只需获取该现有公司,然后将该对象添加到您的Contact。所以让我们这样做:

    # Query the database to find out if we have a company named 'bla'
    company = Company.query.filter_by(company_name="bla").first()
    
    # Did we fail to get a company by the name 'bla'?
    # If so-- lets create one.
    if not company:
        company = Company(company_name="bla")
    
    # Now we're sure to have a company, but not to have a duplicate,
    # Let's create a new contact, and add the company.
    
    contact = Contact(
        last_name="Blabla",
        first_name="Jeff",
        job_position="Resp Marketing",
        contact_status="Client",
    )
    
    # Finally lets commit the contact and associated company to the
    # database.
    
    contact.companies.append(company)
    db.session.add(contact)
    db.session.commit()
    

    【讨论】:

    • 非常感谢@Doobeh,这很好用。我刚刚更改了contact.companies.add(company) --> contact.companies.append(company)。 :)
    【解决方案2】:

    所以: 你的数据库是空的。 你初始化数据库,用 sqlalchemy 创建表...(不记得命令)

    然后你这样做:

    com = Company(company_name='bla')
    con = Contact(last_name='Blabla', first_name='Jeff', job_position='Resp Marketing',contact_status='Client')
    con.companies.append(com)
    db.session.add(con)
    db.session.commit()
    

    然后你这样做:

    #can't remember how to get just one row, is it first instaid of all ? sorry
    com_already_created = Company().query.all()[0] 
    
    con = Contact(last_name='Blabla2', first_name='Jeff2', job_position='Resp Marketing',contact_status='Client')
    
    con.companies.append(com_already_created)
    #or
    com_already_created.contacts.append(con)
    
    db.session.add(con)
    db.session.commit()
    

    您的问题是您正在创建一个元素以添加到已经存在的表 Company 中(我认为您在“Company”模型实现中从“company_name”中删除了 PK 或 unique)

    还有: 检查你的 __repr__,使用 python3.7 f"string" 示例:

        def __repr__(self):
            return '<Contact {}>'.format(self.last_name, self.first_name, 
        self.job_position, self.companys, self.contact_status, self.start_date, 
        self.stop_date)
    
    

    应该是:

    def __repr__(self):
        return f'<Contact PK:{self.id}, lst_nm:{self.last_name}, 
        frst_nm:{self.first_name}, jb_pos:{self.job_position>}, 
        cnt_comp:{len(self.companys)}'
    
    #(add more if you want but its getting messy)
    
    

    【讨论】:

      【解决方案3】:

      这是我用来添加数据的方法。这个很简单。

          com = Company(company_name='bla')
          db.session.add(com)
          con = Contact(last_name='Blabla', first_name='Jeff', job_position='Resp Marketing', 
          companies= [com] , contact_status='Client')
          db.session.add(con)
          db.session.commit()
      

      【讨论】:

      • 首先你需要你初始化数据库,用sqlalchemy创建表。
      猜你喜欢
      • 2014-10-29
      • 2019-04-10
      • 2017-05-04
      • 1970-01-01
      • 2016-06-15
      • 2021-08-31
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多