Уведомления

Группа в Telegram: @pythonsu

#1 Март 16, 2017 21:59:04

ivn
Зарегистрирован: 2017-01-13
Сообщения: 91
Репутация: +  0  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

надо причесать?! причешу ))

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

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

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

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

Офлайн

#2 Март 16, 2017 22:22:00

4kpt_V
От: Харьков
Зарегистрирован: 2017-02-19
Сообщения: 299
Репутация: +  12  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

Кидайте скайп в личку тогда. Спишемся.

Офлайн

#3 Март 27, 2017 17:05:03

ivn
Зарегистрирован: 2017-01-13
Сообщения: 91
Репутация: +  0  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

Тема остановилась на следующей проблеме (дабы не создавать лишней темы):

Есть код, где описана БД и есть связь один ко многим (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
почему это проходит??
т.е. эти данные записываются в БД, а ведь должна возвращаться ошибка.

Офлайн

#4 Март 27, 2017 18:31:24

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

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)



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

Отредактировано PooH (Март 27, 2017 18:33:02)

Офлайн

#5 Март 28, 2017 11:09:03

ivn
Зарегистрирован: 2017-01-13
Сообщения: 91
Репутация: +  0  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

Спасибо за Ваш ответ, обязательно все просмотрю и отпишу!

Офлайн

#6 Март 28, 2017 11:55:12

4kpt_V
От: Харьков
Зарегистрирован: 2017-02-19
Сообщения: 299
Репутация: +  12  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

PooH
Не прибедняйтесь. Там нечего знать

Офлайн

#7 Апрель 25, 2017 16:59:48

ivn
Зарегистрирован: 2017-01-13
Сообщения: 91
Репутация: +  0  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

Спасибо, за помощь.
Сейчас вернулся к этой теме.
Пробую делать следующий код (все по теме, связь один ко многим в пределах одной таблицы):

     __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 (Апрель 25, 2017 19:22:23)

Офлайн

#8 Авг. 15, 2017 15:49:12

ivn
Зарегистрирован: 2017-01-13
Сообщения: 91
Репутация: +  0  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

PooH
не реагировать на ограничение длинны строки - это случайно не входит в тот обычай sqlite?
 db.Column(db.String(45)

Офлайн

#9 Авг. 15, 2017 16:16:07

PooH
От:
Зарегистрирован: 2006-12-05
Сообщения: 1948
Репутация: +  72  -
Профиль   Отправить e-mail  

Flask-SQLAlchemy связь один ко многим в пределах одной таблице

ivn
не реагировать на ограничение длинны строки - это случайно не входит в тот обычай sqlite?
db.Column(db.String(45)
Входит



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

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version