我需要一些帮助来自动化sqlalchemy中的一些任务。 当新用户在我的网站上注册时,我需要添加5个人员。
我想使用sqlalchemy events
,因为如果我可以使用它,它将在以后为其他自动化派上用场。
我正在关注Miguel Grinberg先生关于如何制作烧瓶的教程 application 并定义我的模型(db.Model not Base)。
我读到要使用@event.listens_for(User.__table__, "after_insert")
我必须使用声明性基础。有没有解决的办法?我的模型结构涉及近15个表格!
class User(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
email = db.Column(db.String(64), unique=True, index=True)
username = db.Column(db.String(64), unique=True, index=True)
password_hash = db.Column(db.String(128))
store = db.relationship('Store', uselist=False, backref="user")
@event.listens_for(User.__table__, "after_insert")
def add_personnel(*args, **kwargs):
for i in range(5):
db.session.add(Personnel,store_id = User.query.last().id)
db.session.commit()
return None
class Personnel(db.Model):
__tablename__ = "personnel"
id = db.Column(db.Integer, primary_key=True)
store_id = db.Column(db.Integer, db.ForeignKey('store.id'))
first_name = db.Column(db.String(64))
last_name = db.Column(db.String(64))
username = db.Column(db.String(64))
cell_phone = db.Column(db.Integer)
pin_number = db.Column(db.Integer)
email = db.Column(db.String(64))
orders = db.relationship("Order", backref='personnel', lazy='dynamic')
**TRACEBACK**
Traceback (most recent
call last):
File "manage.py", line 3, in <module>
from app.models import User
File "/home/#######/PycharmProjects/#######/app/models.py", line 62, in <module>
@event.listens_for(User.__table__, "after_insert")
File "/home/#######/PycharmProjects/#######//venv/local/lib/python2.7/site-packages/sqlalchemy/event/api.py", line 124, in decorate
listen(target, identifier, fn, *args, **kw)
File "/home/#######/PycharmProjects/#######/venv/local/lib/python2.7/site-packages/sqlalchemy/event/api.py", line 89, in listen
_event_key(target, identifier, fn).listen(*args, **kw)
File "/home/#######/PycharmProjects/#######/venv/local/lib/python2.7/site-packages/sqlalchemy/event/registry.py", line 194, in listen
dispatch_collection = getattr(target.dispatch, identifier)
File "/home/#######/PycharmProjects/#######/venv/local/lib/python2.7/site-packages/sqlalchemy/event/base.py", line 95, in __getattr__
raise AttributeError(name)
AttributeError: after_insert
答案 0 :(得分:0)
您实际上可以执行此操作,只需按this answer中所述键入@event.listens_for(User, "after_insert")
即可。
请注意,您需要使用SQLAlchemy Connection
而不是您在示例事件中使用的会话。检查this answer,它有很好的处理数据库插入的例子。
答案 1 :(得分:0)
我明白了。这里有两种型号。两者都继承db.Model
。将数据插入InventoryContents
我运行下面定义的事件。现在,如果这不是100%正确使用@db.event.listens_for
我道歉。但是现在它按预期工作。
class MenuContentOrderEntry(db.Model):
__tablename__ = "menu_content_order_entry"
id = db.Column(db.Integer, primary_key=True)
store_id = db.Column(db.Integer, db.ForeignKey('store.id'))
order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
checkout_id = db.Column(db.Integer, db.ForeignKey('checkout.id'), default=None)
menu_item_content_id = db.Column(db.Integer, db.ForeignKey('menu_item_content.id'))
menu_item_id = db.Column(db.Integer, db.ForeignKey('menu_item.id'))
# Todo 24/3/2017 - add name to the contents in case a user deletes it.
content_name = db.Column(db.String(64), default=None)
menu_item_order_id = db.Column(db.Integer, db.ForeignKey('menu_item_order_entry.id'))
# this indicates whether we will print the order or not.
# ignore: 0, print: 1, do not print:2
print_on_pos = db.Column(db.Integer, default=0)
datetime = db.Column(db.String(64), default=func.now(), nullable=False)
# help full columns for inventory
quantity = db.Column(db.Integer, default=0)
default = db.Column(db.Integer, default=None)
changed = db.Column(db.Integer, default=None)
class InventoryContents(db.Model):
"""
This model will show the inventory changes made. Purchases and in-store consumption.
A payee can be a waiter (in-store) or a supplier.
"""
# Todo 14/2/2017 - add some sort of order_date and received_date.
id = db.Column(db.Integer, primary_key=True)
store_id = db.Column(db.Integer, db.ForeignKey('store.id'))
order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
# if an item belongs to a checkout id then it was consumed and money was collected for it.
checkout_id = db.Column(db.Integer, db.ForeignKey('checkout.id'), default=None)
name = db.Column(db.String(64))
datetime = db.Column(db.String(64)) # Todo 14/2/2017 - convert to datetime
payee = db.Column(db.String(64))
units = db.Column(db.String(64)) # [-], kg, L, ml
cost = db.Column(db.Float) # per unit
quantity = db.Column(db.Float) # per unit
revenue = db.Column(db.Float)
@db.event.listens_for(MenuContentOrderEntry, "after_insert")
def add_content_to_inventory_contents(mapper, connection, target):
inv = InventoryContents.__table__
content = MenuItemContent.query.filter_by(id=target.menu_item_content_id).first()
order = Order.query.filter_by(id=target.order_id).first()
waiter_id = order.personnel_id
date_time = order.datetime
waiter_username = Personnel.query.filter_by(id=waiter_id).first().username
content_name = content.name
menu_association = MenuAssociation.query.filter_by(
menu_content_id=target.menu_item_content_id,
menu_item_id=target.menu_item_id).first()
default = target.default
changed = target.changed
flag = False
if (default == 1) and (changed == 1):
flag = False
elif (default == 0) and (changed == 0):
flag = False
elif (default == 1) and (changed == 0):
flag = True
elif (default == 0) and (changed == 1):
flag = True
else:
pass
print(flag)
if not flag:
pass
else:
# Todo 24/3/2017 - add those that are used.
connection.execute(inv.insert().values(store_id=target.store_id,
name=content_name,
order_id=target.order_id,
payee=waiter_username,
datetime=date_time,
cost=menu_association.cost,
quantity=target.quantity))
答案 2 :(得分:0)
我使用参数中的连接就像这样工作。
@db.event.listens_for(Order, "after_insert")
def insert_order_to_printer(mapper, connection, target):
po = PrinterOrder.__table__
connection.execute(po.insert().values(store_id=target.store_id, order_id=target.id, scenario=target.order_type))
订单是:
class Order(db.Model):
#stuff