Найти - Пользователи
Полная версия: Flask-SQLAlchemy связь один ко многим в пределах одной таблице
Начало » Базы данных » Flask-SQLAlchemy связь один ко многим в пределах одной таблице
1 2 3
ivn
надо причесать?! причешу ))

я понимаю, что можно и нужно так добавлять записи.

сам факт добавления такой записи говорит мне что ForeignKey не работает
т.е. это как защита от дурака, что не может быть в поле id_parent числа, которого нет в поле id!
а я добавил!
Иначе к чему весь сыр-бор?

я кстати делал добавления по другим таблицам (где one to many ведут на другие таблицы) и там тоже происходит добавления, а не должно!

ведать, что то до конца я не понимаю. по идее я должен получать ошибку о не возможности добавления такой записи
4kpt_V
Кидайте скайп в личку тогда. Спишемся.
ivn
Тема остановилась на следующей проблеме (дабы не создавать лишней темы):

Есть код, где описана БД и есть связь один ко многим (foreign key) и не ясное до конца поведения скрипта:

 from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
class Role(db.Model):
    __tablename__= 'roles'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(45), unique=True, nullable=False)
    users = db.relationship('User', backref='role')
    def __repr__(self):
        return '<User %r>' % (self.name)
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(45), unique=True, nullable=False)
    # contents = db.relationship('Content', backref='author', lazy='dynamic')
    id_roles = db.Column(db.Integer, db.ForeignKey('roles.id'), nullable=False)
db.create_all()
q = Role(name='admins')
db.session.add(q)
db.session.commit()
q = Role(name='users')
db.session.add(q)
db.session.commit()
q = User(name='admin', id_roles=1)
db.session.add(q)
db.session.commit()
q = User(name='user', id_roles=2)
db.session.add(q)
db.session.commit()
q = User(name='user1', id_roles=222)
db.session.add(q)
db.session.commit()
users = User.query.all()
roles = Role.query.all()
print('{}'.format('roles:'))
for el in roles:
    print(el.id, el.name)
print('{}'.format('users:'))
for el in users:
    print(el.name, el.id_roles)

вот этот код, который делает то чего не могу понять, почему такое происходит:
id_roles=222
почему это проходит??
т.е. эти данные записываются в БД, а ведь должна возвращаться ошибка.
PooH
ivn
почему это проходит??
т.е. эти данные записываются в БД, а ведь должна возвращаться ошибка.
Это старинный красивый обычай особенность sqlite. Поддержка внешних ключей по умолчанию отключена. Вот подробности Вот как включить в sqlalchemy
Вот ваш пример с включенной, только в чистой алхимии, ломает фласк ставить, да и знаю я его плоховато.
  
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, event
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
 
engine = create_engine('sqlite:///test.db', echo=True)
Session = sessionmaker(bind=engine)
Base = declarative_base()
 
@event.listens_for(engine, "connect")
def set_sqlite_pragma(dbapi_connection, connection_record):
    cursor = dbapi_connection.cursor()
    cursor.execute("PRAGMA foreign_keys=ON")
    cursor.close()
 
class Role(Base):
    __tablename__ = 'roles'
    id = Column(Integer, primary_key=True)
    name = Column(String(45), unique=True, nullable=False)
    users = relationship('User', backref='role')
 
    def __repr__(self):
        return '<User %r>' % (self.name)
 
 
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(45), unique=True, nullable=False)
    # contents = relationship('Content', backref='author', lazy='dynamic')
    id_roles = Column(Integer, ForeignKey('roles.id'), nullable=False)
 
Base.metadata.create_all(engine)
 
session = Session()
q = Role(name='admins')
session.add(q)
session.commit()
q = Role(name='users')
session.add(q)
session.commit()
q = User(name='admin', id_roles=1)
session.add(q)
session.commit()
q = User(name='user', id_roles=2)
session.add(q)
session.commit()
q = User(name='user1', id_roles=222)
session.add(q)
session.commit()
users = session.query(User).all()
roles = session.query(Role).all()
print('{}'.format('roles:'))
for el in roles:
    print(el.id, el.name)
print('{}'.format('users:'))
for el in users:
    print(el.name, el.id_roles)
ivn
Спасибо за Ваш ответ, обязательно все просмотрю и отпишу!
4kpt_V
PooH
Не прибедняйтесь. Там нечего знать
ivn
Спасибо, за помощь.
Сейчас вернулся к этой теме.
Пробую делать следующий код (все по теме, связь один ко многим в пределах одной таблицы):

     __tablename__ = 'breadcrumbs'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True, nullable=False)
    id_parent = db.Column(db.Integer, db.ForeignKey('breadcrumbs.id'))
    posts = db.relationship('Post', backref='url_for_posts', lazy='dynamic')
   
    url_breadcrumbs = db.relationship('BreadCrumbs', remote_side=[id], backref=db.backref('bread_crumbs'))

далее добавление новой записи:

 b = BreadCrumbs.query.first()
p = BreadCrumbs(name='Name')
b.bread_crumbs.append(p)
db.session.add(b)
db.session.commit()

получаю:

 sqlalchemy.exc.CircularDependencyError: Circular dependency detected. (SaveUpdateState(<BreadCrumbs at 0x3ed60b0>), ProcessState(OneToManyDP(BreadCrumbs.bread_crumbs), <BreadCrumbs
 at 0x3ed60b0>, delete=False))
ivn
PooH
не реагировать на ограничение длинны строки - это случайно не входит в тот обычай sqlite?
 db.Column(db.String(45)
PooH
ivn
не реагировать на ограничение длинны строки - это случайно не входит в тот обычай sqlite?
db.Column(db.String(45)
Входит
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB