Я относительный новичок в SQLAlchemy и прочитал основную документацию. В настоящее время я следую учебнику Майка Дрисколла по MediaLocker и модифицирую/расширяю его для своих целей.
У меня есть три таблицы (кредиты, люди, карты). Отношения Card to Loan и Person to Loan являются отношениями "один ко многим" и смоделированы следующим образом:
from sqlalchemy import Table, Column, DateTime, Integer, ForeignKey, Unicode
from sqlalchemy.orm import backref, relation
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine("sqlite:///cardsys.db", echo=True)
DeclarativeBase = declarative_base(engine)
metadata = DeclarativeBase.metadata
class Loan(DeclarativeBase):
"""
Loan model
"""
__tablename__ = "loans"
id = Column(Integer, primary_key=True)
card_id = Column(Unicode, ForeignKey("cards.id"))
person_id = Column(Unicode, ForeignKey("people.id"))
date_issued = Column(DateTime)
date_due = Column(DateTime)
date_returned = Column(DateTime)
issue_reason = Column(Unicode(50))
person = relation("Person", backref="loans", cascade_backrefs=False)
card = relation("Card", backref="loans", cascade_backrefs=False)
class Card(DeclarativeBase):
"""
Card model
"""
__tablename__ = "cards"
id = Column(Unicode(50), primary_key=True)
active = Column(Boolean)
class Person(DeclarativeBase):
"""
Person model
"""
__tablename__ = "people"
id = Column(Unicode(50), primary_key=True)
fname = Column(Unicode(50))
sname = Column(Unicode(50))
Когда я пытаюсь создать новый кредит (используя приведенный ниже метод в моем контроллере), он работает нормально для уникальных карт и людей, но как только я пытаюсь добавить второй кредит для определенного человека или карты, он выдает мне ошибку "non-unique". Очевидно, что они не уникальны, в этом и смысл, но я думал, что SQLAlchemy позаботится о закулисных делах за меня, и добавит правильный существующий идентификатор человека или карты в качестве FK в новый заем, вместо того, чтобы пытаться создать новые записи о человеке и карте. Должен ли я делать запрос к базе данных для проверки уникальности PK и обрабатывать это вручную? У меня сложилось впечатление, что SQLAlchemy может справиться с этим автоматически?
def addLoan(session, data):
loan = Loan()
loan.date_due = data["loan"]["date_due"]
loan.date_issued = data["loan"]["date_issued"]
loan.issue_reason = data["loan"]["issue_reason"]
person = Person()
person.id = data["person"]["id"]
person.fname = data["person"]["fname"]
person.sname = data["person"]["sname"]
loan.person = person
card = Card()
card.id = data["card"]["id"]
loan.card = card
session.add(loan)
session.commit()
В примере MediaLocker новые строки создаются с автоматически увеличивающимся PK (даже для дубликатов, что не соответствует правилам нормализации). Я хочу иметь нормализованную базу данных (даже в небольшом проекте, просто для лучшей практики в обучении), но не могу найти в Интернете примеров для изучения.
Как я могу достичь вышеуказанного?