web-dev-qa-db-ja.com

SQLAlchemyで複合主キーを定義する方法

MySQLでSQLAlchemyを使用して、複合主キーを持つテーブルのテーブルマッピングを作成しようとしていますが、正しく実行しているかどうかわかりません。既存のテーブルは複合主キーで定義されます。

マッピングクラスの定義は次のとおりです。

class table1(Base):
    __tablename__ = 'table1'

    col1 = Column(String, primary_key=True)
    col2 = Column(String, primary_key=True)
    col3 = Column(String)

    def __init__ = (self, col1, col2, col3):
        self.col1 = col1
        self.col2 = col2
        self.col3 = col3

これは、データベースa = table1( 'test'、 'test'、 'test')に既に存在するレコードと一致します

これをセッションに追加し、テーブルにレコードを追加してからデータを操作すると、MySQLエラー(1062重複エントリ)が発生します。

session.add(a)
b = session.query(table1)
for instance in b:
    print(instance.col1, instance.col2)

単一キーのテーブルを使用している場合、代わりに次のエラーが発生します。

New instance <table2 at 0x2f204d0> with identity key 
(<class '__main__.table2'>,('test',)) conflicts with 
persistent instance <table2 at 0x2f88770>

複合主キーを誤って定義していますか?そうでない場合、Python/SQLAlchemyエラーの代わりにMySQLエラーを取得するために、何が悪いのでしょうか?

24
Charlie Carwile

質問が曖昧であることに同意します。ただし、以下をガイドラインとして使用できます。これは、MySQLのtestデータベースのtrial1テーブルから選択します。コメントアウトされたパーツは、主キー制約を設定する別の方法としてあります。

from sqlalchemy import String, create_engine, MetaData, Column
from sqlalchemy.ext.declarative import declarative_base
# from sqlalchemy.schema import PrimaryKeyConstraint
from sqlalchemy.orm import sessionmaker

engine = create_engine('mysql+pymysql://root:[email protected]/test')
metadata = MetaData(bind=engine)
Base = declarative_base(metadata=metadata)


class TableClassName(Base):
    __tablename__ = 'table1'

    col1 = Column(String, primary_key=True)
    col2 = Column(String, primary_key=True)
    col3 = Column(String)

    # __table_args__ = (
    #     PrimaryKeyConstraint(
    #         col1,
    #         col2),
    #     {})

Session = sessionmaker(bind=engine)
session = Session()

b = session.query(TableClassName)
for instance in b:
   print(instance.col1, instance.col2)
13
Ali Cirik