使用SQLAlchemy在Postgresql中创建数据库表时出现编程错误

时间:2019-02-18 14:26:05

标签: python postgresql sqlalchemy

我在PostgreSQL中使用SQLAlchemy创建表时遇到问题。

sqlalchemy.exc.ProgrammingError:(psycopg2.ProgrammingError)没有与给定表“ person”的给定键匹配的唯一约束。  [SQL:'\ nCREATE TABLE签署人(\ n \ tid INTEGER NOT NULL,\ n \ tdecree VARCHAR(120),\ n \ tjob_title VARCHAR(120),\ n \ tdate_duty_start TIMESTAMP WITH TIME ZONE,\ n \ tdate_duty_end TIMESTAMP WITHOUT时区,\ n \ tperson_id INTEGER NOT NULL,\ n \ tcompany_id INTEGER NOT NULL,\ n \ tsigner_id INTEGER NOT NULL,\ n \ tcompany_ids INTEGER,\ n \ tperson_ids INTEGER,\ n \ tPRIMARY KEY(id,signer_id), \ n \ tFOREIGN KEY(person_id)参考人(id),\ n \ tFOREIGN KEY(company_id)参考公司(id),\ n \ tFOREIGN KEY(company_ids)参考公司(company_id),\ n \ tFOREIGN KEY(person_ids)参考人员(person_id)\ n)\ n \ n'](此错误的背景位于:http://sqlalche.me/e/f405

我正在尝试创建一个新数据库,因此删除所有表并不能解决问题。而且,我不明白为什么在公司与签署者表之间创建依赖关系没有问题,而人与签署者之间的关系却有问题。...

我的班级如下:

class Person(db.Model):
    __table_args__ = {'extend_existing': True} 
    def __init__ (self, *args, **kwargs):
        [[setattr(self, key, dict[key]) for key in dict if any(key == t for t in Person.__dict__)] for dict in args]

    person_id = db.Column(db.Integer, primary_key = True)
    first_name = db.Column(db.String(30), nullable=False)
    middle_name = db.Column(db.String(40), nullable=False)
    last_name = db.Column(db.String(60), nullable=False)
    email = db.Column(db.String(120))
    license = db.Column(db.String(120))
    address = db.Column(db.String(240))
    telephone = db.Column(db.String(30))

    #o2o
    user_id = db.Column(db.Integer, db.ForeignKey('usersd.user_id'))

    #o2m
    signers = db.relationship('Signer', backref='person_data', lazy='jioned')

    def __repr__(self):
        return f"{self.last_name.Capitalize} {self.first_name[0].Upper}. {self.middle_name[0].Upper}."

class Signer(db.Model):
    __table_args__ = {'extend_existing': True} 

    def __init__ (self, *args, **kwargs):
        [[setattr(self, key, dict[key]) for key in dict if any(key == t for t in Signer.__dict__)] for dict in args]

    signer_id = db.Column(db.Integer, primary_key = True)
    decree = db.Column(db.String(120))
    job_title = db.Column(db.String(120))
    date_duty_start = db.Column(db.DateTime)
    date_duty_end = db.Column(db.DateTime)
    #o2m

    company_ids = db.Column(db.Integer, db.ForeignKey('company.company_id'))
    person_ids = db.Column(db.Integer, db.ForeignKey('person.person_id'))
    #m2o

    def __repr__(self):
        return f"{self.job_title} at {self.company} according to {self.decree}."

class Company(db.Model):
    __table_args__ = {'extend_existing': True} 

    def __init__ (self, *args, **kwargs):
        [[setattr(self, key, dict[key]) for key in dict if any(key == t for t in Company.__dict__)] for dict in args]

    company_id = db.Column(db.Integer, primary_key = True)
    company_name = db.Column(db.String(60))
    full_title = db.Column(db.String(240))
    tin = db.Column(db.BigInteger)
    kpp = db.Column(db.Integer)
    ogrn = db.Column(db.BigInteger)
    email = db.Column(db.String(120))
    address = db.Column(db.String(240))
    telephone = db.Column(db.String(60))

    license_number = db.Column(db.String(40))
    license_date_issued = db.Column(db.DateTime) 
    license_category = db.Column(db.String(120))
    license_issued_by = db.Column(db.String(120))
    license_issued_by_tin = db.Column(db.BigInteger)
    license_issued_by_kpp = db.Column(db.Integer)
    license_issued_by_ogrn = db.Column(db.BigInteger)

    #o2m
    signers = db.relationship('Signer', backref='company', lazy='joined')


    def __repr__(self):
        return f"{self.company_name}"

----------------------
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
import sys
import locale
import datetime





app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:XXXXXXXXXXXXX@localhost/aosr_flask_0_1'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'


------
from test_models import *
db.create_all()

我认为出现问题是因为我试图避免为每个类命名为“ id”的列。尽管我在Postgres DB中将每个类的主键定义为person_id,signer_id,company_id等,但每个表中也都有主键列“ id”。根据Error中给出的SQL,SQL Alchemy尝试针对每种情况创建两个约束...这使其不唯一。

因此,我的问题归结为如何使SQLAlchemy在未指定时不自行创建主键列(ID)。

我试图避免数据库中名为ID的列在以后使用HTML中使用这些对象时出现较少的问题。

1 个答案:

答案 0 :(得分:1)

据我所知,您的问题告诉您没有为主键字段定义唯一选项。您的person_id应该具有unique = True。它将确保该字段不会重复输入ID。

person_id = db.Column(db.Integer, primary_key = True, unique=True)