Nano Hash - криптовалюты, майнинг, программирование

Flask SQL Alchemy Несколько путей соединения и отношения «один ко многим»

Я пытаюсь создать приложение для управления задачами в Flask и столкнулся со следующей проблемой.

У меня есть 3 модели, User, Task и Project. Я хотел бы, чтобы пользователи могли создавать задачи и назначать их другим пользователям. Для этого требуется несколько соединений между моделями Task и User.

Раньше, прежде чем пытаться реализовать эту функцию, у меня было отношение «один ко многим» от User до Task, которое работало нормально, и две исходные модели приведены ниже.

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=True )
    email = db.Column(db.String(120), unique=True, nullable=True)
    password_hash = db.Column(db.String(128))

    tasks = db.relationship('Task', backref='author', lazy='dynamic') # one user has many tasks
    projects = db.relationship('Project', backref='author', lazy='dynamic') # one user has many projects

class Task(UserMixin, db.Model):
    __tablename__ = 'tasks'
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(128))
    due = db.Column(db.DateTime, index=True)
    done = db.Column(db.Boolean, default=False)
    author_id = db.Column(db.Integer, db.ForeignKey('users.id')) # task belongs to user
    project_id = db.Column(db.Integer, db.ForeignKey('projects.id')) # task belongs to project

Следуя документации SQL Alchemy, Я добавил столбец assigned_to_id в задачу и столбец assigned_tasks в пользователь.

Мои модели теперь следующие:

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=True )
    email = db.Column(db.String(120), unique=True, nullable=True)
    password_hash = db.Column(db.String(128))
    tasks_id = db.Column(db.Integer, db.ForeignKey('tasks.id'))
    assigned_tasks_id = db.Column(db.Integer, db.ForeignKey('tasks.id'))

    tasks = db.relationship('Task', foreign_keys="User.tasks_id", backref='author') # one user has many tasks
    assigned_tasks = db.relationship('Task', foreign_keys="User.tasks_id", backref='assigned_to') # one user has many tasks
    projects = db.relationship('Project', backref='author', lazy='dynamic') # one user has many projects

class Task(UserMixin, db.Model):
    __tablename__ = 'tasks'
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(128))
    due = db.Column(db.DateTime, index=True)
    done = db.Column(db.Boolean, default=False)
    author_id = db.Column(db.Integer, db.ForeignKey('users.id')) # task belongs to user
    assigned_to_id = db.Column(db.Integer, db.ForeignKey('users.id'))
    project_id = db.Column(db.Integer, db.ForeignKey('projects.id')) # task belongs to project

Поскольку у меня нет ограничений на задачи, которые необходимо назначать, или на пользователей, которым необходимо назначать задачи, я предположил, что смогу продолжать создавать пользователей и задачи, как раньше. Но теперь, когда я пытаюсь создать задачу с автором, я получаю ошибку.

>>> u = User(email='[email protected]', password='password')
>>> t = Task(body='New Task', author=u)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<string>", line 4, in __init__
  File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/orm/state.py", line 417, in _initialize_instance
    manager.dispatch.init_failure(self, args, kwargs)
  File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 249, in reraise
    raise value
  File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/orm/state.py", line 414, in _initialize_instance
    return manager.original_init(*mixed[1:], **kwargs)
  File "/Users/Jasmine/projects/flask/tasky/app/models.py", line 67, in __init__
    super(Task, self).__init__(**kwargs)
  File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/ext/declarative/base.py", line 700, in _declarative_constructor
    setattr(self, k, kwargs[k])
  File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/orm/attributes.py", line 229, in __set__
    instance_dict(instance), value, None)
  File "/Users/Jasmine/projects/flask/tasky/venv/lib/python3.7/site-packages/sqlalchemy/orm/attributes.py", line 1040, in set
    given, wanted))
TypeError: Incompatible collection type: User is not list-like

Я, возможно, неправильно понял здесь ошибку, но мне кажется, что теперь каждая задача ожидает более одного автора. Как сохранить отношение «один ко многим», чтобы каждая задача по-прежнему ожидала только одного автора?


Ответы:


1

Я не могу добавить комментарий из-за своей репутации, но One-to-many Flask | SQLAlchemy

принятый ответ здесь должен помочь вам. Также...

>>> u = User(email='[email protected]', password='password')
>>> t = Task(body='New Task', author=u)

переменная автора не существует в классе Task, поскольку она существует в классе User

Вам нужно добавить пользователя к задаче. Возможно, вы захотите просмотреть свой код, отношения между классами кажутся неправильными. Это или я ошибаюсь.

01.08.2018
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..