Мой первый вопрос / пост ... пожалуйста, будьте добры ....
Я работаю над личным проектом, в котором один модуль работает в цикле сбора данных.Когда данные поступают, они вручную вставляют данные в базу данных в функцию в очереди, где прослушивающий сотрудник 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»должен импортировать "базу".Это оказалось проблемой, поскольку, как только работник запускает функцию collect_data (называемую «передача»), он больше не может найти файлы для импорта, и работник выдает исключение, говоря, что не может импортировать базу.».Я искал ответы в Интернете и в конце концов нашел ответ на Github от nvie, в котором упоминалось, как направить работника по правильному пути, используя параметр --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).
Итак, после долгого объяснения мой вопрос: Как правильно управлять путями в этом случае?Мне кажется неправильным, что я должен использовать свой полный путь из / home ... Я что-то упускаю из-за того, как работают пути и / или rq работник (и тому подобное)?
Ниже приведены выдержки из моих файлов кода:
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, а затем запускаю работника с:
$rq worker rq_worker_data2db --path /home/../../collect_view/DataCollection (где rq_worker_data2db - имя работника)