2015-10-16 316 views
2

我有一個使用flask.ext.sqlalchemyapscheduler.schedulers.background的Python Flask應用程序。我創建了一個作業存儲,並得到一個名爲apscheduler_jobs表具有以下字段:如何將APScheduler JobStore與SQLAlchemy模型(外鍵)相關聯 - Python Flask

|id |next_run_time|job_state| 
------------------------------ 
|TEXT| REAL  | TEXT | 

我想涉及的SQLAlchemy的模型對象到該表使用類似這樣的:

from apscheduler.schedulers.background import BackgroundScheduler 
scheduler = BackgroundScheduler() 
scheduler.add_jobstore('sqlalchemy', url=app.config['SQLALCHEMY_DATABASE_URI']) 

class Event(db.Model): 

    __tablename__ = "event" 

    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    name = db.Column(db.String(255), nullable=False) 
    jobs = db.relationship('scheduler', backref='apscheduler_jobs') 

所以我想使用APScheduler apscheduler_jobs中的表格,然後將其與外鍵關聯到我的Event對象。最後一行將有基本上打破的「調度」不是一個定義SQLAlchmey模型

qlalchemy.exc.InvalidRequestError: When initializing mapper Mapper|Event|event, expression 'scheduler' failed to locate a name ("name 'scheduler' is not defined"). If this is a class name, consider adding this relationship() to the <class 'project.models.Event'> class after both dependent classes have been defined. 

所以我想我需要所謂的「工作」或類似的插圖中的Model類,則涉及,要apscheduler_jobs,但這裏的東西仍然感覺不好 - 因爲APScheduler正在製作這張桌子,我無法控制那裏正在發生的事情 - 我應該關注嗎?

EDIT1: 所以我創建了2個型號,一個「事件」,那麼一個「作業」,「作業」,那麼涉及到表apscheduler_jobs

class Job(db.Model): 

    __tablename__ = "job" 
    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    name = db.Column(db.String(255), nullable=False) 
    apscheduler_job_id = db.Column(db.Integer, db.ForeignKey('apscheduler_jobs.id')) 
    event_id = db.Column(db.Integer, db.ForeignKey('event.id')) 

問題存在,當我放棄了DB和重建它它拋出的錯誤:

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'job.apscheduler_job_id' could not find table 'apscheduler_jobs' with which to generate a foreign key to target column 'id'

現在我能得到解決,在我的數據庫創建腳本,但同樣它仍然感覺就像我DOI NG這種錯誤的方式

EDIT2 我設法得到它的工作,雖然這感覺很不對勁,我現在已經有3種型號:事件,工作,和APSchedulerJobsTable。最終模型基本上與APScheduler apscheduler_jobs的外觀相匹配。必須有更好的方法來做到這一點。

from project import db 


class Event(db.Model): 

    __tablename__ = "event" 

    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    name = db.Column(db.String(255), nullable=False) 
    jobs = db.relationship('Job', backref='job_event') 


class Job(db.Model): 

    __tablename__ = "job" 

    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    apscheduler_job_id = db.Column(db.TEXT, db.ForeignKey('apscheduler_jobs.id')) 
    event_id = db.Column(db.Integer, db.ForeignKey('event.id')) 


class APSchedulerJobsTable(db.Model): 
    # TODO: This feels bad man 
    __tablename__ = "apscheduler_jobs" 

    id = db.Column(db.TEXT, primary_key=True, autoincrement=True) 
    next_run_time = db.Column(db.REAL) 
    job_state = db.Column(db.TEXT) 

回答

1

好了,兩種解決方案 - 既不是真正的完美IMO:

解決方案一,可能更清潔 - 只需在包含aspscheduler_job_ids工作表中的文本字段 - 這是不是一個外鍵雖然但一旦aspscheduler_job ID是已知的有可能繼續下去,並將其存儲在工作表中,供日後參考

class Event(db.Model): 

    __tablename__ = "event" 

    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    name = db.Column(db.String(255), nullable=False) 
    jobs = db.relationship('Job', backref='job_event') 


class Job(db.Model): 

    __tablename__ = "job" 

    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    event_id = db.Column(db.Integer, db.ForeignKey('event.id')) 
    apscheduler_job_id = db.Column(db.TEXT) 

抓住了這個人是爲了砸滿DB你需要運行的第是包括丟棄的非託管表apscheduler_jobs

db.reflect() 
db.drop_all() 

解決方案二,則apscheduler表添加到模型本身,然後設置外鍵:

class Event(db.Model): 

    __tablename__ = "event" 

    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    name = db.Column(db.String(255), nullable=False) 
    jobs = db.relationship('Job', backref='job_event') 


class Job(db.Model): 

    __tablename__ = "job" 

    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    event_id = db.Column(db.Integer, db.ForeignKey('event.id')) 
    apscheduler_job_id = db.Column(db.TEXT, db.ForeignKey('apscheduler_jobs.id')) 


class APSchedulerJobsTable(db.Model): 
    # TODO: This feels bad man 
    __tablename__ = "apscheduler_jobs" 

    id = db.Column(db.TEXT, primary_key=True, autoincrement=True) 
    next_run_time = db.Column(db.REAL) 
    job_state = db.Column(db.TEXT) 
    job = db.relationship('Job', backref='job_event') 
相關問題