微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SQLAlchemy+PostgreSQL+pyscopg2+Flask-Admin 和 ARRAY(ForeignKey) 不获取 'dialect_impl'

如何解决SQLAlchemy+PostgreSQL+pyscopg2+Flask-Admin 和 ARRAY(ForeignKey) 不获取 'dialect_impl'

我是 sqlAlchemy 和 Flask-Admin 的新手。我正在为现有的 Postgresql 数据库架构编写 Flask-Admin 应用程序。该模式使用 int[] 来表示多个实体上的一对多(例如,一个 Surface 实体可以有多个 Image 实体)。使用关联表(relation table)不是当前循环的选项。

我可以将它用作 ARRAY(Integer) 字段并且它可以工作。我宁愿显示友好的图像名称。我尝试使用 SelectMultipleField 并且无法弄清楚如何将它与图像外键的 int[] 一起使用。

我切换到下面的代码(简化为重要语句),它似乎几乎可以工作,除了我得到: 应用程序中的错误:/admin/surface/ [GET] 上的异常 ...

AttributeError: 'ForeignKey' object has no attribute 'dialect_impl'

myFlaskModel.py

    from flask_sqlalchemy import sqlAlchemy

    db = sqlAlchemy()

    Base = db.Model

    #
    def bind_app_to_db(app,dbname):
    '''
      helper function that connects/binds a Flask app to
      a database
    '''
    app.config['SECRET_KEY'] = "mysecret"
    app.config['sqlALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://uname:upwd@localhost{str(dbname)}'
    # perhaps deepcopy db for multiple database case
    db.init_app(app)
    return app,db
    class Image(Base):
        """
        Fields:
          "img_id" serial NOT NULL PRIMARY KEY,"img_title" text NULL,"img_url" text,"img_scratch" text NULL
        """
        typeLbl = 'img'
        __tablename__ = 'image'
    
        img_id = db.Column(db.Integer,nullable=False,primary_key=True)
        img_title = db.Column(db.Text,nullable=True)
        img_url = db.Column(db.Text,nullable=True)
        img_scratch = db.Column(db.Text,nullable=True)
        srf_images = db.relationship('Surface',backref='images',primaryjoin='Image.img_id==any_(foreign(Surface.srf_image_ids))')
    
    # define declarative model for dynamic binding to database_name parameter 
    class Surface(Base):
        """
        Fields:
          "srf_id" serial NOT NULL PRIMARY KEY,"srf_label" text NULL,"srf_image_ids" int[] NULL,"srf_scratch" text NULL
        """
        typeLbl = 'srf'
        __tablename__ = 'surface'

        srf_id = db.Column(db.Integer,primary_key=True)
        srf_label = db.Column(db.Text,nullable=True)
        srf_image_ids = db.Column(db.ARRAY(db.ForeignKey(Image.img_id)),nullable=True)
        srf_scratch = db.Column(db.Text,nullable=True)

MyFlaskView.py

    from flask_admin.contrib.sqla import ModelView


    def addAllViews(admin,fm,db):
        ''' adds all READ Views to the passed flask admin object '''
        admin.add_view(ImageView(fm.Image,db.session,category="Source"))
        admin.add_view(SurfaceView(fm.Surface,category="Physical"))

    class SurfaceView(ModelView):
        column_exclude_list = ['srf_scratch']
        can_delete = False
        column_display_pk = True
        column_display_all_relations = True
        can_view_details = True
        edit_modal = True
        details_modal = True
        column_filters = ('srf_id','srf_label','srf_scratch')
        column_default_sort = 'srf_id'
        column_labels = dict(srf_id='ID',srf_label='Label',srf_image_ids='Image IDs',images='Images',srf_scratch='Scratch')

        def on_model_change(self,form,model,is_created):
            model.srf_image_ids = [int(x) for x in model.srf_image_ids]

myApp.py

   from flask import Flask,request,redirect
   from flask_admin import Admin,AdminIndexView
   import myFlaskModel as fm
   import myFlaskView as fv

   app = Flask(__name__)


   @app.route('/')
   def index():
       dbname = request.args.get('db')
       if dbname is None:
           return "<h1> Hello ?db=dbname is require to view a database!</h1>"
       else:
           boundApp,appDB = fm.bind_app_to_db(app,dbname)
           # bind admin to the app and attach dbname to menubar
           admin = Admin(boundApp,template_mode='bootstrap4',index_view=AdminIndexView(
                           name=dbname
                         ))
           # add Views to Flask_Admin app
           fv.addAllViews(admin,appDB)

           return redirect('/admin')


   if __name__ == '__main__':
       app.run()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。