sqlalchemy.exc.ProgrammingError:(psycopg2.errors.InvalidForeignKey)没有与引用表“dicom”的给定键匹配的唯一约束

问题描述 投票:0回答:2

基本上,在 models.py 中的 Flask 应用服务器上,您使用类在 PostgreSQL 上调用 ORM,但是如果您执行一对一关系或一对多关系。如果您没有将密钥定义为“唯一”,您可能会收到错误消息。在postgresql中,所有外键必须引用父表中的唯一键,因此在您的bar表中,您必须有一个唯一(名称)索引。最后,我们应该提到外键必须引用主键或表单的列唯一的约束。

Traceback (most recent call last):
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\engine\base.py", line 1248, in _execute_context
    cursor, statement, parameters, context
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\engine\default.py", line 588, in do_execute
    cursor.execute(statement, parameters)
psycopg2.errors.InvalidForeignKey: there is no unique constraint matching given keys for referenced table "dicom"     


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\lesli\AppData\Local\Programs\Python\Python37\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Users\lesli\AppData\Local\Programs\Python\Python37\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "D:\L_pipe\vessel_app_celery\vessel_env\Scripts\flask.exe\__main__.py", line 9, in <module>
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\flask\cli.py", line 990, in main
    cli.main(args=sys.argv[1:])
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\flask\cli.py", line 596, in main
    return super().main(*args, **kwargs)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\click\core.py", line 1062, in main
    rv = self.invoke(ctx)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\click\core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\click\core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\click\core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\click\core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\click\decorators.py", line 26, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\flask\cli.py", line 440, in decorator
    return __ctx.invoke(f, *args, **kwargs)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\click\core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\flask_migrate\cli.py", line 134, in upgrade
    _upgrade(directory, revision, sql, tag, x_arg)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\flask_migrate\__init__.py", line 95, in wrapped
    f(*args, **kwargs)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\flask_migrate\__init__.py", line 280, in upgrade     
    command.upgrade(config, revision, sql=sql, tag=tag)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\command.py", line 298, in upgrade
    script.run_env()
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\script\base.py", line 489, in run_env        
    util.load_python_file(self.dir, "env.py")
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\util\pyfiles.py", line 98, in load_python_file
    module = load_module_py(module_id, path)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\util\compat.py", line 184, in load_module_py 
    spec.loader.exec_module(module)
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "migrations\env.py", line 96, in <module>
    run_migrations_online()
  File "migrations\env.py", line 90, in run_migrations_online
    context.run_migrations()
  File "<string>", line 8, in run_migrations
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\runtime\environment.py", line 846, in run_migrations
    self.get_context().run_migrations(**kw)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\runtime\migration.py", line 520, in run_migrations
    step.migration_fn(**kw)
  File "D:\L_pipe\vessel_app_celery\Vessel-app\Back-end\migrations\versions\9ea0138f3052_.py", line 228, in upgrade   
    sa.PrimaryKeyConstraint('id')
  File "<string>", line 8, in create_table
  File "<string>", line 3, in create_table
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\operations\ops.py", line 1252, in create_table
    return operations.invoke(op)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\operations\base.py", line 374, in invoke     
    return fn(self, operation)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\operations\toimpl.py", line 101, in create_table
    operations.impl.create_table(table)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\ddl\impl.py", line 258, in create_table      
    self._exec(schema.CreateTable(table))
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\alembic\ddl\impl.py", line 140, in _exec
    return conn.execute(construct, *multiparams, **params)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\engine\base.py", line 984, in execute     
    return meth(self, multiparams, params)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\sql\ddl.py", line 72, in _execute_on_connection
    return connection._execute_ddl(self, multiparams, params)
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\engine\base.py", line 1046, in _execute_ddl
    compiled,
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\engine\base.py", line 1288, in _execute_context
    e, statement, parameters, cursor, context
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\engine\base.py", line 1482, in _handle_dbapi_exception
    sqlalchemy_exception, with_traceback=exc_info[2], from_=e
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\util\compat.py", line 178, in raise_      
    raise exception
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\engine\base.py", line 1248, in _execute_context
    cursor, statement, parameters, context
  File "d:\l_pipe\vessel_app_celery\vessel_env\lib\site-packages\sqlalchemy\engine\default.py", line 588, in do_execut    cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.InvalidForeignKey) there is no unique constraint matching given keys for referenced table "dicom"

[SQL:
CREATE TABLE "DicomFormData" (
        id SERIAL NOT NULL,
        session_id VARCHAR(200) NOT NULL,
        date_uploaded TIMESTAMP WITHOUT TIME ZONE NOT NULL,
        study_name VARCHAR(300) NOT NULL,
        description VARCHAR(1000) NOT NULL,
        PRIMARY KEY (id),
)

]
python sqlalchemy
2个回答
0
投票

解决方案 需要使用 db.Unique Constraint 添加表参数

class Dicom(db.Model):
    
    __tablename__ = 'dicom'
    ## data unqine id 
    __table_args__ = (
        # this can be db.PrimaryKeyConstraint if you want it to be a primary key
        db.UniqueConstraint('session_id'),
    )

    id = db.Column(db.Integer, primary_key=True)  
    date_uploaded = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) 
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    userReact_id = db.Column(db.Integer, db.ForeignKey('UserReact.id'), nullable=True)
    dicom_stack = db.Column(db.LargeBinary, nullable=False)
    thumbnail = db.Column(db.LargeBinary, nullable=False)
    file_count = db.Column(db.Integer, nullable=True) 
    session_id = db.Column(db.String(200), nullable=False)
     #uselist one to one relationship
    formData = db.relationship('DicomFormData', uselist=True, backref='author', lazy=True)
  
    def __repr__(self):
        return f"Dicom('{self.date_uploaded}')"

class DicomFormData(db.Model):

    id = db.Column(db.Integer, primary_key=True)  
    date_uploaded = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) 
    study_name = db.Column(db.String(300), nullable=False) 
    description = db.Column(db.String(1000), nullable=False)
    session_id = db.Column(db.String(200), db.ForeignKey('dicom.session_id'), nullable=False)

    def __repr__(self):
        return f"DicomFormData('{self.study_name}')"

0
投票
class Dicom(db.Model):

__tablename__ = 'dicom'

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

这是我今天刚学到的东西。

我还有一个列声明为primary_key,但flask-migrate没有将其检测为唯一约束。

我想传递参数 unique 就是解决这个问题的方法。因为我看到,当我传递唯一参数时,flask-migrate 会检测到此更改,即向名为“id”的表添加新的唯一约束。

© www.soinside.com 2019 - 2024. All rights reserved.