我在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中使用这些对象时出现较少的问题。
答案 0 :(得分:1)
据我所知,您的问题告诉您没有为主键字段定义唯一选项。您的person_id应该具有unique = True。它将确保该字段不会重复输入ID。
person_id = db.Column(db.Integer, primary_key = True, unique=True)