[英]Python Sqlalchemy mysql “Cannot add or update a child row: a foreign key constraint fails”
I'm trying to create a simple realtional database using sqlalchemy and mysql. 我正在尝试使用sqlalchemy和mysql创建一个简单的实际数据库。 I'm not sure what I'm doing wrong, although I think it could be something to do with the way I'm adding the rows to the table.
我不确定自己在做什么错,尽管我认为这可能与我向表中添加行的方式有关。 My models are below and the code that creates all the entries below that.
我的模型在下面,并且在下面创建所有条目的代码。
This is the error I'm getting: 这是我得到的错误:
2014-03-12 14:53:52,109 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
INFO:sqlalchemy.engine.base.Engine:BEGIN (implicit)
2014-03-12 14:53:52,139 INFO sqlalchemy.engine.base.Engine INSERT INTO accession_numbers (accession_number, gene) VALUES (%s, %s)
INFO:sqlalchemy.engine.base.Engine:INSERT INTO accession_numbers (accession_number, gene) VALUES (%s, %s)
2014-03-12 14:53:52,140 INFO sqlalchemy.engine.base.Engine (('AB009589', <__main__.Gene object at 0xe8ba090>), ('AB014887', <__main__.Gene object at 0xe220890>), ('AB019534', <__main__.Gene object at 0xe8baf10>), ('AB038490', <__main__.Gene object at 0xe8b8150>), ('AB046409', <__main__.Gene object at 0xe8b86d0>), ('AB051625', <__main__.Gene object at 0xe8b8c50>), ('AB051627', <__main__.Gene object at 0xe8b8ed0>), ('AB060808', <__main__.Gene object at 0xe8dd110>) ... displaying 10 of 1317 total bound parameter sets ... ('EU266531', <__main__.Gene object at 0x15093b50>), ('EU286279', <__main__.Gene object at 0x15093cd0>))
INFO:sqlalchemy.engine.base.Engine:(('AB009589', <__main__.Gene object at 0xe8ba090>), ('AB014887', <__main__.Gene object at 0xe220890>), ('AB019534', <__main__.Gene object at 0xe8baf10>), ('AB038490', <__main__.Gene object at 0xe8b8150>), ('AB046409', <__main__.Gene object at 0xe8b86d0>), ('AB051625', <__main__.Gene object at 0xe8b8c50>), ('AB051627', <__main__.Gene object at 0xe8b8ed0>), ('AB060808', <__main__.Gene object at 0xe8dd110>) ... displaying 10 of 1317 total bound parameter sets ... ('EU266531', <__main__.Gene object at 0x15093b50>), ('EU286279', <__main__.Gene object at 0x15093cd0>))
2014-03-12 14:53:52,143 INFO sqlalchemy.engine.base.Engine ROLLBACK
INFO:sqlalchemy.engine.base.Engine:ROLLBACK
---------------------------------------------------------------------------
IntegrityError Traceback (most recent call last)
<ipython-input-17-96f4786cad50> in <module>()
29 session.add(acc)
30
---> 31 session.commit()
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.pyc in commit(self)
719 raise sa_exc.InvalidRequestError("No transaction is begun.")
720
--> 721 self.transaction.commit()
722
723 def prepare(self):
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.pyc in commit(self)
352 self._assert_active(prepared_ok=True)
353 if self._state is not PREPARED:
--> 354 self._prepare_impl()
355
356 if self._parent is None or self.nested:
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.pyc in _prepare_impl(self)
332 if self.session._is_clean():
333 break
--> 334 self.session.flush()
335 else:
336 raise exc.FlushError(
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.pyc in flush(self, objects)
1822 try:
1823 self._flushing = True
-> 1824 self._flush(objects)
1825 finally:
1826 self._flushing = False
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.pyc in _flush(self, objects)
1940 except:
1941 with util.safe_reraise():
-> 1942 transaction.rollback(_capture_exception=True)
1943
1944 def is_modified(self, instance, include_collections=True,
/usr/lib64/python2.7/site-packages/sqlalchemy/util/langhelpers.pyc in __exit__(self, type_, value, traceback)
56 exc_type, exc_value, exc_tb = self._exc_info
57 self._exc_info = None # remove potential circular references
---> 58 compat.reraise(exc_type, exc_value, exc_tb)
59 else:
60 self._exc_info = None # remove potential circular references
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.pyc in _flush(self, objects)
1904 self._warn_on_events = True
1905 try:
-> 1906 flush_context.execute()
1907 finally:
1908 self._warn_on_events = False
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyc in execute(self)
370 self.dependencies,
371 postsort_actions):
--> 372 rec.execute(self)
373
374 def finalize_flush_changes(self):
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/unitofwork.pyc in execute(self, uow)
523 persistence.save_obj(self.mapper,
524 uow.states_for_mapper_hierarchy(self.mapper, False, False),
--> 525 uow
526 )
527
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/persistence.pyc in save_obj(base_mapper, states, uowtransaction, single)
62 _emit_insert_statements(base_mapper, uowtransaction,
63 cached_connections,
---> 64 table, insert)
65
66 _finalize_insert_update_commands(base_mapper, uowtransaction,
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/persistence.pyc in _emit_insert_statements(base_mapper, uowtransaction, cached_connections, table, insert)
539 multiparams = [rec[2] for rec in records]
540 c = cached_connections[connection].\
--> 541 execute(statement, multiparams)
542
543 for (state, state_dict, params, mapper,
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.pyc in execute(self, object, *multiparams, **params)
660 object,
661 multiparams,
--> 662 params)
663 else:
664 raise exc.InvalidRequestError(
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_clauseelement(self, elem, multiparams, params)
759 compiled_sql,
760 distilled_params,
--> 761 compiled_sql, distilled_params
762 )
763 if self._has_events:
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
872 parameters,
873 cursor,
--> 874 context)
875
876 if self._has_events:
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.pyc in _handle_dbapi_exception(self, e, statement, parameters, cursor, context)
1022 self.dialect.dbapi.Error,
1023 connection_invalidated=self._is_disconnect),
-> 1024 exc_info
1025 )
1026
/usr/lib64/python2.7/site-packages/sqlalchemy/util/compat.pyc in raise_from_cause(exception, exc_info)
194 # the code line where the issue occurred
195 exc_type, exc_value, exc_tb = exc_info
--> 196 reraise(type(exception), exception, tb=exc_tb)
197
198
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.pyc in _execute_context(self, dialect, constructor, statement, parameters, *args)
854 statement,
855 parameters,
--> 856 context)
857 elif not parameters and context.no_parameters:
858 self.dialect.do_execute_no_params(
/usr/lib64/python2.7/site-packages/sqlalchemy/connectors/mysqldb.pyc in do_executemany(self, cursor, statement, parameters, context)
58
59 def do_executemany(self, cursor, statement, parameters, context=None):
---> 60 rowcount = cursor.executemany(statement, parameters)
61 if context is not None:
62 context._rowcount = rowcount
/usr/lib64/python2.7/site-packages/MySQLdb/cursors.pyc in executemany(self, query, args)
204 r = 0
205 for a in args:
--> 206 r = r + self.execute(query, a)
207 return r
208 p = m.start(1)
/usr/lib64/python2.7/site-packages/MySQLdb/cursors.pyc in execute(self, query, args)
172 del tb
173 self.messages.append((exc, value))
--> 174 self.errorhandler(self, exc, value)
175 self._executed = query
176 if not self._defer_warnings: self._warning_check()
/usr/lib64/python2.7/site-packages/MySQLdb/connections.pyc in defaulterrorhandler(***failed resolving arguments***)
34 del cursor
35 del connection
---> 36 raise errorclass, errorvalue
37
38 re_numeric_part = re.compile(r"^(\d+)")
IntegrityError: (IntegrityError) (1452, 'Cannot add or update a child row: a foreign key constraint fails (`chromo9`.`accession_numbers`, CONSTRAINT `accession_numbers_ibfk_1` FOREIGN KEY (`gene`) REFERENCES `genes` (`gene_identifier`))') 'INSERT INTO accession_numbers (accession_number, gene) VALUES (%s, %s)' (('AB009589', <__main__.Gene object at 0xe8ba090>), ('AB014887', <__main__.Gene object at 0xe220890>), ('AB019534', <__main__.Gene object at 0xe8baf10>), ('AB038490', <__main__.Gene object at 0xe8b8150>), ('AB046409', <__main__.Gene object at 0xe8b86d0>), ('AB051625', <__main__.Gene object at 0xe8b8c50>), ('AB051627', <__main__.Gene object at 0xe8b8ed0>), ('AB060808', <__main__.Gene object at 0xe8dd110>) ... displaying 10 of 1317 total bound parameter sets ... ('EU266531', <__main__.Gene object at 0x15093b50>), ('EU286279', <__main__.Gene object at 0x15093cd0>))
my models: 我的模特:
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, Text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import ForeignKey
from sqlalchemy.orm import sessionmaker
SETTINGS = {
'DB':{
'USER':'root',
'LOCATION':'localhost',
'PORT':'3306',
'DATABASE_NAME':'chromo9',
},
}
class Settings:
def __init__(self, **attrs):
for key, value in attrs.iteritems():
if type(value) is dict:
attrs[key] = Settings(**value)
self.__dict__.update(attrs)
SETTINGS = Settings(**SETTINGS)
if not hasattr(SETTINGS.DB, 'PASSWD'):
SETTINGS.DB.PASSWD = raw_input('Enter passwd for mysql user {}'.format(SETTINGS.DB.USER))
conn_string = 'mysql+mysqldb://{user}:{passwd}@{location}:{port}'.format(
user = SETTINGS.DB.USER,
passwd = SETTINGS.DB.PASSWD,
location = SETTINGS.DB.LOCATION,
port = SETTINGS.DB.PORT,
)
#engine = create_engine('sqlite:///:memory:', )#echo=True)
engine = create_engine(conn_string, echo=True)
engine.execute('CREATE DATABASE IF NOT EXISTS {}'.format(SETTINGS.DB.DATABASE_NAME))
engine.execute('USE {}'.format(SETTINGS.DB.DATABASE_NAME))
Base = declarative_base()
class Gene(Base):
__tablename__ = 'genes'
gene_identifier= Column(Integer, primary_key=True)
nucleotide_sequence = Column(Text)
chromosome_location = Column(String(8))
class Accession(Base):
__tablename__ = 'accession_numbers'
accession_number = Column(String(8), primary_key=True)
gene = Column(Integer, ForeignKey('genes.gene_identifier'))
class Exon(Base):
__tablename__ = 'exons'
id = Column(Integer, primary_key=True)
start = Column(Integer)
end = Column(Integer)
gene = Column(Integer, ForeignKey('genes.gene_identifier'))
class Protein(Base):
__tablename__ = 'proteins'
id = Column(Integer, primary_key=True)
name = Column(String(128))
sequence = Column(Text)
gene = Column(Integer, ForeignKey('genes.gene_identifier'))
Base.metadata.create_all(engine) # create the tables
Creating all the objects: 创建所有对象:
Session = sessionmaker(bind=engine)
session = Session()
for record in records:
gene = Gene(gene_identifier=record.gi ,nucleotide_sequence=record.sequence ,chromosome_location=record.locus)
session.add(gene)
for feature in record.features:
if feature.key == 'CDS':
translation, name = None, None
for qualifier in feature.qualifiers:
if qualifier.key == '/translation=':
translation = qualifier.value
if qualifier.key == '/product=':
name = qualifier.value
# create protein object
protein = Protein(name=name, sequence=translation, gene=gene)
session.add(protein)
if feature.key == 'exon':
start, end = feature.location.split('..')
start, end = int(''.join([d for d in start if d.isdigit()])), int(''.join([d for d in end if d.isdigit()]))
exon = Exon(start=start,end=end,gene=gene)
session.add(exon)
for accession in record.accession:
acc = Accession(accession_number=accession, gene=gene)
session.add(acc)
session.commit()
There was a lot to look through, so I'm sure I missed something, but since I'm not sure how much you know about the database you're working with, I'll start with this and hope it helps: 有很多东西需要浏览,所以我确定我错过了一些东西,但是由于我不确定您对正在使用的数据库了解多少,因此我将从此开始,希望对您有所帮助:
It looks like you're trying to insert an Accession that references a Gene that doesn't exist. 似乎您正在尝试插入引用不存在的基因的登录。 That's the Foreign Key that it's complaining about.
那就是它所抱怨的外键。 It looks like you try to create the Gene and the Accession in the same session.
似乎您尝试在同一会话中创建基因和登录。 You might need to call session.commit() after creating the Gene (and any other objects that are relied upon by later updates).
创建基因(以及以后的更新所依赖的任何其他对象)之后,您可能需要调用session.commit()。 That will put the Gene in the DB, which can then be referenced by the Accession.
这会将基因放入数据库,然后可以由登录号引用。
That's a bit of a shot in the dark, as I'm not familiar with SQLAlchemy (and have no idea what an Accession is). 因为我对SQLAlchemy不熟悉(并且不知道什么是Accession),所以在黑暗中拍了一下。 I'm just relying on my knowledge of SQL here.
我只是依靠我对SQL的了解。 But the issue is definitely getting any rows into the gene table BEFORE rows in tables that rely on the gene table are inserted.
但是问题绝对是在插入依赖于基因表的表中的行之前,将任何行插入基因表中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.