#python #sqlite #sqlalchemy #flask-sqlalchemy
#python #sqlite #sqlalchemy #flask-sqlalchemy
Вопрос:
У меня есть модель продукта, а также варианты модели продукта. Я хочу создать отношения «многие ко многим» между моделями продуктов и моделью категории (включая варианты продукта, которые наследуются от базовой модели продукта).
product_category = db.Table('product_category', db.Model.metadata,
db.Column('product_id', db.Integer, db.ForeignKey('product.id'), primary_key=True),
db.Column('category_id', db.Integer, db.ForeignKey('category.id'), primary_key=True)
)
class Category(db.Model):
__table_name__ = 'category'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(MaxLengths.category_name))
# products = db.relationship('Product', secondary='product_category')
def __repr__(self):
return '<Category %s>' % self.name
class Product(db.Model):
'''
Generic Product Model - this is the parent of SubProducts for specific purposes
'''
id = db.Column(db.Integer, primary_key=True)
product_type = db.Column(
db.String(MaxLengths.product_type), nullable=False)
name = db.Column(db.String(MaxLengths.product_name),
unique=True, nullable=False)
price = db.Column(db.Float())
description = db.Column(
db.String(MaxLengths.product_description), nullable=False)
categories = db.relationship('Category', secondary=product_category)
reviews = db.relationship('Review', backref='product')
orders_count = db.Column(db.Integer, default=0)
stock = db.Column(db.Integer(), nullable=False)
order_id = db.Column(db.Integer, db.ForeignKey('orders.id'))
is_raffle_product = db.Column(db.Boolean, default=False)
raffle_start_date = db.Column(ArrowType)
raffle_end_date = db.Column(ArrowType)
__mapper_args__ = {
'polymorphic_identity': 'product',
'polymorphic_on': product_type
}
class ProductVariant(Product):
id = db.Column(db.Integer, db.ForeignKey('product.id'), primary_key=True)
prices = db.Column(db.JSON(), nullable=False) # This is a list object
weights = db.Column(db.JSON(), nullable=False)
__mapper_args__ = {'polymorphic_identity': 'product_variant'}
Однако при попытке создать вариант модели продукта со следующим кодом я получаю следующую ошибку
db.drop_all()
db.create_all()
product = ProductVariant(name="test product")
category = Category(name='test category')
product.categories.append(category)
[jack@DESKTOP-6FAK8Q8 DIRECTORY]$ ./flask.sh testdb
[ ] Started redis-server
/usr/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py:833: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
warnings.warn(FSADeprecationWarning(
/usr/lib/python3.9/site-packages/sqlalchemy/sql/ddl.py:903: SAWarning: Can't sort tables for DROP; an unresolvable foreign key dependency exists between tables: discount_code, orders, user; and backend does not support ALTER. To restore at least a partial sort, apply use_alter=True to ForeignKey and ForeignKeyConstraint objects involved in the cycle to mark these as known cycles that will be ignored.
util.warn(
Traceback (most recent call last):
File "/usr/sbin/flask", line 33, in <module>
sys.exit(load_entry_point('Flask==1.1.2', 'console_scripts', 'flask')())
File "/usr/lib/python3.9/site-packages/flask/cli.py", line 967, in main
cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
File "/usr/lib/python3.9/site-packages/flask/cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "/usr/lib/python3.9/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/usr/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/lib/python3.9/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/usr/lib/python3.9/site-packages/click/decorators.py", line 21, in new_func
return f(get_current_context(), *args, **kwargs)
File "/usr/lib/python3.9/site-packages/flask/cli.py", line 426, in decorator
return __ctx.invoke(f, *args, **kwargs)
File "/usr/lib/python3.9/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/mnt/d/code/python/DIRECTORY/commands.py", line 29, in testdb
product_variant = ProductVariant(name='test product', product_type="product_variant")
File "<string>", line 4, in __init__
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/state.py", line 433, in _initialize_instance
manager.dispatch.init_failure(self, args, kwargs)
File "/usr/lib/python3.9/site-packages/sqlalchemy/util/langhelpers.py", line 68, in __exit__
compat.raise_(
File "/usr/lib/python3.9/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
raise exception
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/state.py", line 430, in _initialize_instance
return manager.original_init(*mixed[1:], **kwargs)
File "<string>", line 6, in __init__
File "/usr/lib/python3.9/site-packages/sqlalchemy/ext/declarative/base.py", line 842, in _declarative_constructor
setattr(self, k, kwargs[k])
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 272, in __set__
self.impl.set(
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 1334, in set
collections.bulk_replace(
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/collections.py", line 801, in bulk_replace
appender(member, _sa_initiator=initiator)
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/collections.py", line 1116, in append
item = __set(self, item, _sa_initiator)
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/collections.py", line 1081, in __set
item = executor.fire_append_event(item, _sa_initiator)
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/collections.py", line 717, in fire_append_event
return self.attr.fire_append_event(
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 1176, in fire_append_event
value = fn(state, value, initiator or self._append_token)
File "/usr/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 1485, in emit_backref_from_collection_append_event
child_state, child_dict = instance_state(child), instance_dict(child)
AttributeError: 'str' object has no attribute '_sa_instance_state'
[-] redis-server has shutdown
Комментарии:
1. Ваше определение таблицы категорий неверно. Удалите
product_id =
иcategory_id =
. Имена столбцов определяются первым аргументомColumn
.2. Большое вам спасибо, я тоже только что это заметил, хотя, к сожалению, сейчас я получаю другую ошибку :/
3. Ошибка, которую вы получаете, не связана ни с одним из вышеперечисленных. Между пользователем, кодом скидки и заказами существует несвязанная зависимость от внешнего ключа.