我的第一个问题/帖子...请保持友善....
我正在做一个个人项目,其中一个模块循环运行以收集数据。当数据输入时,它将把数据插入数据库中的操作交给队列中的某个函数,侦听的rq工作者在该队列中将其提取并处理该函数。使用SQLAlchemy管理数据库,这意味着它必须生成引擎,会话并定义数据库表。
代码文件的结构为:
--/home/..../collect-view/ (this is the project folder)
-- DataCollection
-- main_client.py (main loop waiting for user data)
-- collect_data.py (contains the database insertion function)
-- base.py (the base file for SQLAlchemy database definition)
-- tables.py (the file which sets up the table name and definition)
-- app.db (the database file)
请注意:该数据库文件位于更高级别的目录中,因为它也可以由位于该级别的另一个应用程序(Flask应用程序)访问
要实现此代码,“ collect_data”必须导入“ base”,“ tables”和“ tables”必须导入“ base”。事实证明,这是一个问题,因为一旦worker运行了collect_data函数(称为“ transfer”),它便不再能找到要导入的文件,而worker吐出了一个异常,说它无法导入“ base” ”。我在网上搜索了答案,最终在nvie的Github上找到了答案,其中提到使用--path选项将工作程序定向到正确的路径。我通过实施来使其工作:
$ rq worker rq_worker_data2db --path /home/../../collect_view/DataCollection
然后,我遇到了另一个与路径相关的故障,其中工作人员说找不到我要插入数据的数据库表。因此,我更改了引擎创建步骤,也包括了完整的路径...
base_url = '/home/.../collect_view/'
engine = create_engine ('sqlite:///' + base_url + 'app.db')
由于我的工作人员已经在我的DataCollection目录中工作了,所以这个问题令我更加困惑,所以我认为('sqlite:///../app.db')是定位数据库的正确方法(就像在没有rq worker的测试过程中一样。)
因此,经过长时间的解释,我的问题是:在这种情况下管理路径的正确方法是什么?我似乎必须从/ home使用完整路径,这对我来说似乎是错误的。我是否缺少有关路径和/或rq worker(及类似工具)工作方式的信息?
从我的代码文件中提取的内容如下:
main_client.py
from redis import Redis
import rq
from collect_data import transfer
redis_url = Redis.from_url('redis://') #(config['REDIS_URL'])
queue = rq.Queue('rq_worker-data2db', connection=redis_url)
#.....
#.....
def have_data(data):
rq_job = queue.enqueue('collect_data.transfer', data)
#.....
#.....
collect_data.py
from base import Session, engine, Base
from tables import FieldData
import time
from datetime import datetime
def transfer(info):
timestamp_in = datetime.utcnow()
session = Session()
data1 = FieldData(data=info, timestamp=timestamp_in)
session.add(data1)
session.commit()
base.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
base_url = '/home/.../collect_view/'
engine = create_engine ('sqlite:///' + base_url + 'app.db')
Session = sessionmaker(bind=engine)
Base = declarative_base()
tables.py
from sqlalchemy import Column, String, Float, Integer, Date, DateTime, Table, ForeignKey
from base import Base
from datetime import datetime
# .....
#.....
class FieldData(Base):
__tablename__ = 'field_data'
id = Column(Integer, primary_key=True)
data = Column(String(20))
timestamp = Column(DateTime, index=True, default=datetime.utcnow)
def __init__(self, data, timestamp):
self.data = data
self.timestamp = timestamp
首先在终端中运行Redis,然后使用以下命令运行worker:
$ rq worker rq_worker_data2db --path /home/../../collect_view/DataCollection (其中rq_worker_data2db是工作程序名称)