如何解决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 举报,一经查实,本站将立刻删除。