SQLAlchemy 多对多 UNIQUE 约束关联失败 table
SQLAlchemy many-to-many UNIQUE constraint failed association table
我把tables 'projects'和'project_freelancer'通过多对多的关系连接起来,因为一个项目可以有多个freelancer,一个freelancer可以做多个项目。
在 'projects' 中我只有一个主键 'url'。
在 'projects_freelancer' 中,我有一个来自 'url' 和 'freel_url'
的复合主键
因此我这样定义我的协会table:
association_table = Table('association', Base.metadata,
Column('projects_url', ForeignKey('projects.url', ondelete="CASCADE"), primary_key=True),
Column('project_freelancer_url'),
Column('project_freelancer_freel_url'),
ForeignKeyConstraint(
('project_freelancer_url', 'project_freelancer_freel_url'),
('project_freelancer.url', 'project_freelancer.freel_url')),
)
这是我的 class-定义(简短版):
class Project(Base):
__tablename__ = "projects"
url = Column(String, primary_key=True)
datetime = Column(DateTime)
children2 = relationship("ProjectFree", secondary=association_table, back_populates='parents2', cascade="all, delete") # Many-to-many relationship
class ProjectFree(Base):
__tablename__ = "project_freelancer"
url = Column(String, primary_key=True)
freel_url = Column(String, primary_key=True)
update = Column(DateTime)
parents2 = relationship("Project", secondary=association_table, back_populates="children2", cascade="all, delete")
填充数据库时出现以下错误消息:
ERROR [21-11-18 09:58:47] scrapy.core.scraper _itemproc_finished :249 Error processing {'added': datetime.datetime(2021, 11, 18, 9, 58, 47, 654089),
'freel_bidtext': 'Hi,\n'
'\n'
'I hope all is well with you.\n'
'\n'
'I have read the job description and finds it a perfect '
'match for me as I have extensive hands-on experience in '
'React JS/Vue JS development.\n'
'\n'
'I have developed a lot of websites and sto',
'freel_country': 'Pakistan',
'freel_deadline': 'in 7 days',
'freel_earnings': '0.0',
'freel_name': 'abdulhaseebbasit',
'freel_price': '0 USD',
'freel_ranking': 3,
'freel_rating': '0.0',
'freel_reviews': '0',
'freel_url': 'https://www.freelancer.com/u/abdulhaseebbasit',
'update': datetime.datetime(1900, 1, 1, 0, 0),
'url': 'https://www.freelancer.com/projects/javascript/looking-for-react-developer-32135012/?ngsw-bypass=&w=f'}
Traceback (most recent call last):
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1802, in _execute_context
self.dialect.do_execute(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\default.py", line 719, in do_execute
cursor.execute(statement, parameters)
sqlite3.IntegrityError: UNIQUE constraint failed: association.projects_url
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\twisted\internet\defer.py", line 858, in _runCallbacks
current.result = callback( # type: ignore[misc]
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\scrapy\utils\defer.py", line 150, in f
return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
File "C:\Users\myuser\PycharmProjects\crawlerDiss\diss\diss\pipelines.py", line 42, in process_item
return self.handle_ProjectFreelancer(item, spider)
File "C:\Users\myuser\PycharmProjects\crawlerDiss\diss\diss\pipelines.py", line 160, in handle_ProjectFreelancer
session.commit()
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1428, in commit
self._transaction.commit(_to_root=self.future)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 829, in commit
self._prepare_impl()
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 808, in _prepare_impl
self.session.flush()
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3345, in flush
self._flush(objects)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3485, in _flush
transaction.rollback(_capture_exception=True)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
compat.raise_(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3445, in _flush
flush_context.execute()
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 456, in execute
rec.execute(self)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 579, in execute
self.dependency_processor.process_saves(uow, states)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\dependency.py", line 1182, in process_saves
self._run_crud(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\dependency.py", line 1245, in _run_crud
connection.execute(statement, secondary_insert)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1289, in execute
return meth(self, multiparams, params, _EMPTY_EXECUTION_OPTS)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\sql\elements.py", line 325, in _execute_on_connection
return connection._execute_clauseelement(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1481, in _execute_clauseelement
ret = self._execute_context(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1845, in _execute_context
self._handle_dbapi_exception(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 2026, in _handle_dbapi_exception
util.raise_(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1802, in _execute_context
self.dialect.do_execute(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\default.py", line 719, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: association.projects_url
[SQL: INSERT INTO association (projects_url, project_freelancer_url, project_freelancer_freel_url) VALUES (?, ?, ?)]
[parameters: ('https://www.freelancer.com/projects/javascript/looking-for-react-developer-32135012/?ngsw-bypass=&w=f', 'https://www.freelancer.com/projects/javascript/looking-for-react-developer-32135012/?ngsw-bypass=&w=f', 'https://www.freelancer.com/u/abdulhaseebbasit')]
(Background on this error at: https://sqlalche.me/e/14/gkpj)
在我看到的 db-browser 中,只有唯一的组合被填充到关联中 table。因此,对于已经在协会 table 中的项目,与不同的自由职业者发生错误。你知道我必须改变什么吗?我应该在任何地方更改独特的行为吗?
我终于找到了解决方案,而且非常简单(这种情况经常发生)。在关联 table 中,我必须为每个外键添加 , primary_key = True
。这是最后的 association_table
:
association_table = Table('association', Base.metadata,
Column('projects_url', ForeignKey('projects.url', ondelete="CASCADE"), primary_key=True),
Column('project_freelancer_url', primary_key = True),
Column('project_freelancer_freel_url', primary_key = True),
ForeignKeyConstraint(
('project_freelancer_url', 'project_freelancer_freel_url'),
('project_freelancer.url', 'project_freelancer.freel_url')),
)
我通过阅读文档提示想到了这个想法 here。
我把tables 'projects'和'project_freelancer'通过多对多的关系连接起来,因为一个项目可以有多个freelancer,一个freelancer可以做多个项目。 在 'projects' 中我只有一个主键 'url'。 在 'projects_freelancer' 中,我有一个来自 'url' 和 'freel_url'
的复合主键因此我这样定义我的协会table:
association_table = Table('association', Base.metadata,
Column('projects_url', ForeignKey('projects.url', ondelete="CASCADE"), primary_key=True),
Column('project_freelancer_url'),
Column('project_freelancer_freel_url'),
ForeignKeyConstraint(
('project_freelancer_url', 'project_freelancer_freel_url'),
('project_freelancer.url', 'project_freelancer.freel_url')),
)
这是我的 class-定义(简短版):
class Project(Base):
__tablename__ = "projects"
url = Column(String, primary_key=True)
datetime = Column(DateTime)
children2 = relationship("ProjectFree", secondary=association_table, back_populates='parents2', cascade="all, delete") # Many-to-many relationship
class ProjectFree(Base):
__tablename__ = "project_freelancer"
url = Column(String, primary_key=True)
freel_url = Column(String, primary_key=True)
update = Column(DateTime)
parents2 = relationship("Project", secondary=association_table, back_populates="children2", cascade="all, delete")
填充数据库时出现以下错误消息:
ERROR [21-11-18 09:58:47] scrapy.core.scraper _itemproc_finished :249 Error processing {'added': datetime.datetime(2021, 11, 18, 9, 58, 47, 654089),
'freel_bidtext': 'Hi,\n'
'\n'
'I hope all is well with you.\n'
'\n'
'I have read the job description and finds it a perfect '
'match for me as I have extensive hands-on experience in '
'React JS/Vue JS development.\n'
'\n'
'I have developed a lot of websites and sto',
'freel_country': 'Pakistan',
'freel_deadline': 'in 7 days',
'freel_earnings': '0.0',
'freel_name': 'abdulhaseebbasit',
'freel_price': '0 USD',
'freel_ranking': 3,
'freel_rating': '0.0',
'freel_reviews': '0',
'freel_url': 'https://www.freelancer.com/u/abdulhaseebbasit',
'update': datetime.datetime(1900, 1, 1, 0, 0),
'url': 'https://www.freelancer.com/projects/javascript/looking-for-react-developer-32135012/?ngsw-bypass=&w=f'}
Traceback (most recent call last):
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1802, in _execute_context
self.dialect.do_execute(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\default.py", line 719, in do_execute
cursor.execute(statement, parameters)
sqlite3.IntegrityError: UNIQUE constraint failed: association.projects_url
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\twisted\internet\defer.py", line 858, in _runCallbacks
current.result = callback( # type: ignore[misc]
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\scrapy\utils\defer.py", line 150, in f
return deferred_from_coro(coro_f(*coro_args, **coro_kwargs))
File "C:\Users\myuser\PycharmProjects\crawlerDiss\diss\diss\pipelines.py", line 42, in process_item
return self.handle_ProjectFreelancer(item, spider)
File "C:\Users\myuser\PycharmProjects\crawlerDiss\diss\diss\pipelines.py", line 160, in handle_ProjectFreelancer
session.commit()
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1428, in commit
self._transaction.commit(_to_root=self.future)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 829, in commit
self._prepare_impl()
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 808, in _prepare_impl
self.session.flush()
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3345, in flush
self._flush(objects)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3485, in _flush
transaction.rollback(_capture_exception=True)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 70, in __exit__
compat.raise_(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\session.py", line 3445, in _flush
flush_context.execute()
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 456, in execute
rec.execute(self)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 579, in execute
self.dependency_processor.process_saves(uow, states)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\dependency.py", line 1182, in process_saves
self._run_crud(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\orm\dependency.py", line 1245, in _run_crud
connection.execute(statement, secondary_insert)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1289, in execute
return meth(self, multiparams, params, _EMPTY_EXECUTION_OPTS)
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\sql\elements.py", line 325, in _execute_on_connection
return connection._execute_clauseelement(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1481, in _execute_clauseelement
ret = self._execute_context(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1845, in _execute_context
self._handle_dbapi_exception(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 2026, in _handle_dbapi_exception
util.raise_(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_
raise exception
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1802, in _execute_context
self.dialect.do_execute(
File "c:\users\myuser\pycharmprojects\crawlerdiss\venv\lib\site-packages\sqlalchemy\engine\default.py", line 719, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: association.projects_url
[SQL: INSERT INTO association (projects_url, project_freelancer_url, project_freelancer_freel_url) VALUES (?, ?, ?)]
[parameters: ('https://www.freelancer.com/projects/javascript/looking-for-react-developer-32135012/?ngsw-bypass=&w=f', 'https://www.freelancer.com/projects/javascript/looking-for-react-developer-32135012/?ngsw-bypass=&w=f', 'https://www.freelancer.com/u/abdulhaseebbasit')]
(Background on this error at: https://sqlalche.me/e/14/gkpj)
在我看到的 db-browser 中,只有唯一的组合被填充到关联中 table。因此,对于已经在协会 table 中的项目,与不同的自由职业者发生错误。你知道我必须改变什么吗?我应该在任何地方更改独特的行为吗?
我终于找到了解决方案,而且非常简单(这种情况经常发生)。在关联 table 中,我必须为每个外键添加 , primary_key = True
。这是最后的 association_table
:
association_table = Table('association', Base.metadata,
Column('projects_url', ForeignKey('projects.url', ondelete="CASCADE"), primary_key=True),
Column('project_freelancer_url', primary_key = True),
Column('project_freelancer_freel_url', primary_key = True),
ForeignKeyConstraint(
('project_freelancer_url', 'project_freelancer_freel_url'),
('project_freelancer.url', 'project_freelancer.freel_url')),
)
我通过阅读文档提示想到了这个想法 here。