sqlalchemy关联对象-复合主键和现有对象问题

时间:2018-11-18 11:35:22

标签: python python-3.x sqlalchemy

我有以下代码尝试使用关联对象创建父子多对多关系。 ParentChild(关联表)要有一个包含parent_id,child_id和unc

的组合键
timestamp.
import os
import sys
import psycopg2
from datetime import datetime
from sqlalchemy import Column, ForeignKey, Integer, String, Date
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, Session
from sqlalchemy import create_engine

Base = declarative_base()

class ParentChild(Base):
   __tablename__ = 'parentchild'
   parent_id = Column(Integer, ForeignKey('parent.id'), primary_key=True)
   child_id = Column(Integer, ForeignKey('child.id'), primary_key=True)
   timestamp = Column(Date, primary_key=True)
   child = relationship("Child", back_populates="parents")
   parent = relationship("Parent", back_populates="children")

class Parent(Base):
   __tablename__ = 'parent'
   id = Column(Integer, autoincrement=True, primary_key=True)
   name = Column(String)
   age = Column(Integer)
   children = relationship('ParentChild', back_populates="parent")

class Child(Base):
   __tablename__ = 'child'
   id = Column(Integer, autoincrement=True, primary_key=True)
   name = Column(String)
   age = Column(Integer)
   parents = relationship('ParentChild', back_populates='child')


engine = create_engine('blah blah blah')
Base.metadata.create_all(engine)
session = Session(engine)

parent1 = Parent(name='Mark', age='28')
session.add(parent1)

child1 = Child(name='Jack', age='3')
session.add(child1)

family1 = ParentChild(timestamp = datetime.utcnow())
family1.child = child1.id 
parent1.children.append(family1)

session.add(family1)
session.commit()

这会导致错误消息;

SAWarning: Column 'parentchild.child_id' is marked as a member of the primary key for table 'parentchild', but has no Python-side or server-side default generator indicated, nor does it indicate 'autoincrement=True' or 'nullable=True', and no explicit value is passed.  Primary key columns typically may not store NULL. Note that as of SQLAlchemy 1.1, 'autoincrement=True' must be indicated explicitly for composite (e.g. multicolumn) primary keys if AUTO_INCREMENT/SERIAL/IDENTITY behavior is expected for one of the columns in the primary key. CREATE TABLE statements are impacted by this change as well on most backends.
  util.warn(msg)
Traceback (most recent call last):
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\engine\base.py", line 1193, in _execute_context
    context)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\engine\default.py", line 509, in do_execute
    cursor.execute(statement, parameters)
psycopg2.IntegrityError: null value in column "child_id" violates not-null constraint
DETAIL:  Failing row contains (2, null, 2018-11-18).


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

Traceback (most recent call last):
  File "c:/Users/markp/OneDrive/Code/agile_metrics/test_assoc.py", line 50, in <module>
    session.commit()
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\session.py", line 954, in commit
    self.transaction.commit()
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\session.py", line 467, in commit
    self._prepare_impl()
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\session.py", line 447, in _prepare_impl
    self.session.flush()
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\session.py", line 2313, in flush
    self._flush(objects)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\session.py", line 2440, in _flush
    transaction.rollback(_capture_exception=True)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\util\langhelpers.py", line 66, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\util\compat.py", line 249, in reraise
    raise value
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\session.py", line 2404, in _flush
    flush_context.execute()
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 395, in execute
    rec.execute(self)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 560, in execute
    uow
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\persistence.py", line 181, in save_obj
    mapper, table, insert)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\persistence.py", line 872, in _emit_insert_statements
    execute(statement, params)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\engine\base.py", line 948, in execute
    return meth(self, multiparams, params)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\sql\elements.py", line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\engine\base.py", line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\engine\base.py", line 1200, in _execute_context
    context)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\engine\base.py", line 1413, in _handle_dbapi_exception
    exc_info
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\util\compat.py", line 265, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\util\compat.py", line 248, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\engine\base.py", line 1193, in _execute_context
    context)
  File "C:\Users\markp\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\engine\default.py", line 509, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) null value in column "child_id" violates not-null constraint
DETAIL:  Failing row contains (2, null, 2018-11-18).
 [SQL: 'INSERT INTO parentchild (parent_id, timestamp) VALUES (%(parent_id)s, %(timestamp)s)'] [parameters: {'parent_id': 2, 'timestamp': datetime.datetime(2018, 11, 18, 11, 25, 34, 667000)}] (Background on this error at: http://sqlalche.me/e/gkpj)

关于如何解决此问题的任何想法?

谢谢 标记

0 个答案:

没有答案