我正在使用基于项目管理的python 3.4,Flask和SQLAlchemy开发项目。我有以下类需要在多对多关系中相互链接。用户和项目模块按预期单独运行。 用户型号代码包含在
下面class User(db.Model):
__tablename__='users'
id = db.Column(db.Integer, primary_key =True)
firstname = db.Column(db.String(80))
lastname = db.Column(db.String(80))
email = db.Column(db.String(35), unique =True)
username = db.Column(db.String(80), unique= True)
password = db.Column(db.String(80))
organisation_id = db.Column(db.Integer, db.ForeignKey('organisations.id'))
organisation = db.relationship('Organisation', backref='users')
is_admin = db.Column(db.Boolean)
def __init__(self, firstname, lastname, email, username, password, organisation_id, is_admin=False):
self.firstname = firstname
self.email = email
self.lastname = lastname
self.password = password
self.is_admin = is_admin
self.username = username
organisation_id = organisation_id
项目的代码是
class Project(db.Model):
__tablename__ ="projects"
id = db.Column(db.Integer, primary_key=True)
code = db.Column(db.String(80), unique=True)
name = db.Column(db.String(80))
owner = db.Column(db.Integer, db.ForeignKey('users.id'))
description = db.Column(db.Text)
start = db.Column(db.DateTime)
finish = db.Column(db.DateTime)
cycle_id = db.Column(db.Integer, db.ForeignKey('reportingcycles.id'))
cycle= db.relationship('ReportingCycle', backref='project')
org_id = db.Column(db.Integer, db.ForeignKey('organisations.id'))
organisation= db.relationship('Organisation', backref='project')
status = db.Column(db.Boolean)
users = db.relationship("UserProject", backref="project")
def __init__(self, code, name, description, owner, start, finish, cycle, organisation, status):
self.code = code
self.name = name
self.owner = owner
self.description = description
self.start = start
self.finish = finish
self.status = status
self.org_id= organisation.id
self.cycle_id= cycle.id
我已根据此链接Association Object中的SQLAlchemy教程创建了一个关联对象 关联类的代码是
class UserProject(db.Model):
__tablename__ = 'user_project'
project_id = db.Column(db.Integer, db.ForeignKey('projects.id'), primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
role_id = db.Column(db.Integer)
user = db.relationship("User", backref="project_assocs")
当我尝试通过键入以下代码
在命令行中测试此关系时prj = Project.query.first()
usr = User.query.first()
asso = UserProject(role_id =1)
asso.user = usr
prj.users.append(asso)
尝试将这些更改提交到数据库时出现以下错误。
/home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/sql/crud.py:692: SAWarning:列' user_project.project_id'被标记为。的成员 表' user_project'的主键,但没有Python端或 指示服务器端默认生成器,也不指示 '自动增量=真'或者' nullable = True',没有明确的值 通过。主键列通常可能不存储NULL。注意 从SQLAlchemy 1.1开始,' autoincrement = True'必须表明 明确表示复合(例如多列)主键if 其中一个的预期为AUTO_INCREMENT / SERIAL / IDENTITY行为 主键中的列。 CREATE TABLE语句受到影响 这种变化也适用于大多数后端。 util.warn(msg)回溯(大多数 最近的呼叫最后一次):文件"",第1行,在文件中 " /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/attributes.py" ;, 第237行,获取 return self.impl.get(instance_state(instance),dict_)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/attributes.py" , 第584行,在得到 value = self.callable_(state,passive)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/strategies.py", 第557行,在_load_for_state中 返回self._emit_lazyload(session,state,ident_key,passive)文件"",第1行,在File中 " /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/strategies.py" ;, 第635行,在_emit_lazyload中 result = q.all()File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/query.py", 总共2703行 返回列表(个体)文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/query.py", 第2854行, iter self.session._autoflush()File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/session.py", 第1375行,在_autoflush中 util.raise_from_cause(e)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py", 第203行,在raise_from_cause中 reraise(type(exception),exception,tb = exc_tb,cause = cause)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py& #34 ;, 第187行,重新加入 提高价值文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/session.py", 第1365行,在_autoflush中 self.flush()File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/session.py", 第2139行,同花顺 self._flush(objects)文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/session.py", 第2259行,在_flush transaction.rollback(_capture_exception = True)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/util/langhelpers.py", 第66行,在退出 compat.reraise(exc_type,exc_value,exc_tb)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py", 第187行,重新加入 提高价值文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/session.py", 第2223行,在_flush flush_context.execute()File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/unitofwork.py", 第389行,执行中 rec.execute(self)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/unitofwork.py", 第548行,执行中 uow File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", 第181行,在save_obj中 mapper,table,insert)文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", 第835行,在_emit_insert_statements中 执行(声明,参数)文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py", 第945行,执行中 return meth(self,multiparams,params)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/sql/elements.py", 第263行,在_execute_on_connection中 return connection._execute_clauseelement(self,multiparams,params)文件 " /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py" ;, 第1053行,在_execute_clauseelement中 compiled_sql,distilled_params File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py", 第1189行,在_execute_context中 context)文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py", 第1394行,在_handle_dbapi_exception中 exc_info文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py", 第203行,在raise_from_cause中 reraise(type(exception),exception,tb = exc_tb,cause = cause)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/util/compat.py& #34 ;, 第186行,重新加入 提高value.with_traceback(tb)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/engine/base.py", 第1182行,在_execute_context中 context)文件" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/sqlalchemy/engine/default.py", 第470行,在do_execute中 cursor.execute(statement,parameters)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/cursors.py", 第146行,执行中 result = self._query(query)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/cursors.py", 第296行,在_query中 conn.query(q)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/connections.py", 第781行,在查询中 self._affected_rows = self._read_query_result(unbuffered = unbuffered)文件 " /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/connections.py" ;, 第942行,在_read_query_result中 result.read()File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/connections.py", 第1138行,正在阅读中 first_packet = self.connection._read_packet()File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/connections.py", 第906行,在_read_packet中 packet.check_error()File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/connections.py", 第367行,在check_error中 err.raise_mysql_exception(self._data)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/err.py", 第120行,在raise_mysql_exception中 _check_mysql_exception(errinfo)File" /home/ubuntu/workspace/colp/venv/lib/python3.4/site-packages/pymysql/err.py", 第_ 112行,在_check_mysql_exception中 raise errorclass(errno,errorvalue)sqlalchemy.exc.IntegrityError :(由于Query-invoked autoflush引发;考虑使用 session.no_autoflush阻止此过早发生此刷新) (pymysql.err.IntegrityError)(1452,'无法添加或更新子行: 外键约束失败(
colp
。user_project
,CONSTRAINTuser_project_ibfk_1
外键(project_id
)参考projects
(id
))')[SQL:' INSERT INTO user_project(user_id,role_id)VALUES (%s,%s)'] [参数:(1,1)]
知道我在这段代码中做错了什么
答案 0 :(得分:0)
在分析了错误的问题后,我知道它只在你创建一个新的用户(对象),一个新的/现有的项目(对象)时工作,然后如果你关联,它将正常工作。当我在下面做的时候,我得到了它的工作:
prj = Project(status=True //with other parameters) or prj = Project.query.first()
usr = User(is_admin=True //with other parameters)
asso = UserProject(role_id =1)
asso.user = usr
prj.users.append(asso)
但是如果我尝试对现有对象做同样的事情,我会得到与你相同的错误。这可能有助于进一步调查:)
答案 1 :(得分:0)
我已经找到了一个受@Pradeepb之前的响应启发的工作,他发现代码只有在定义了新对象时才有效。不确定它是最好的,但它的工作原理。 这是通过添加构造函数
来修改UserProject类来实现的class UserProject(db.Model):
__tablename__ = 'user_project'
project_id = db.Column(db.Integer, db.ForeignKey('projects.id'), primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
role_id = db.Column(db.Integer)
user = db.relationship("User", backref="parent_assocs")
project = db.relationship("Project", backref="assoc")
def __init__(self, project, user, role):
self.project_id = project.id
self.user_id = user.id
self.role_id = role.id
使用来自DB的现有资源添加关联我使用了代码
prj = Project.query.first()
usr = User.query.first()
asso = UserProject(project = prj, user=usr, role_id =1)