Error using sqlalchemy to create tables in postgresql - sqlalchemy

I am working with sqlalchemy (python 2.7) trying to create several tables in a postgresql (9.5) database. ubuntu 16.04
Using the abstraction of sqlalchemy I am having problems creating the tables with their primary and foreign keys for some reason.
Any help would be much appreciated.
Stacktrace and Error message and source code lastly:
Traceback (most recent call last):
File "create_db.py", line 49, in <module>
Base.metadata.create_all(engine)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/sql/schema.py", line 3918, in create_all
tables=tables)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1929, in _run_visitor
conn._run_visitor(visitorcallable, element, **kwargs)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1538, in _run_visitor
**kwargs).traverse_single(element)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 121, in traverse_single
return meth(obj, **kw)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/sql/ddl.py", line 733, in visit_metadata
_is_metadata_operation=True)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py", line 121, in traverse_single
return meth(obj, **kw)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/sql/ddl.py", line 767, in visit_table
include_foreign_key_constraints=include_foreign_key_constraints
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 945, in execute
return meth(self, multiparams, params)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/sql/ddl.py", line 68, in _execute_on_connection
return connection._execute_ddl(self, multiparams, params)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1002, in _execute_ddl
compiled
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context
context)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1402, in _handle_dbapi_exception
exc_info
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context
context)
File "/home/chris/workspace/final_project/env/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 470, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) there is no unique constraint matching given keys for referenced table "filerecord"
[SQL: '\nCREATE TABLE prodrecord (\n\tproductcode INTEGER NOT NULL, \n\tproductname VARCHAR(80), \n\tproductversion VARCHAR(80), \n\topsystemcode VARCHAR(50) NOT NULL, \n\tmfgcode VARCHAR(50) NOT NULL, \n\tlanguage VARCHAR(80), \n\tapplicationtype VARCHAR(80), \n\tPRIMARY KEY (productcode, opsystemcode, mfgcode), \n\tUNIQUE (productcode, opsystemcode, mfgcode), \n\tFOREIGN KEY(productcode) REFERENCES filerecord (productcode), \n\tFOREIGN KEY(opsystemcode) REFERENCES osrecord (opsystemcode), \n\tFOREIGN KEY(mfgcode) REFERENCES mfgrecord (mfgcode)\n)\n\n']
create_db.py source
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
from sqlalchemy.schema import UniqueConstraint
Base = declarative_base()
class FileRecord(Base):
__tablename__ = 'filerecord'
sha1 = Column(String(80))
md5 = Column(String(80))
crc32 = Column(String(80))
filename = Column(String(80))
filesize = Column(Integer)
productcode = Column(Integer, primary_key=True, unique=True)
opsystemcode = Column(String(50))
specialcode = Column(String(50))
class MfgRecord(Base):
__tablename__ = 'mfgrecord'
mfgcode = Column(String(80), primary_key=True, unique=True)
mfgname = Column(String(80))
class OSRecord(Base):
__tablename__ = 'osrecord'
opsystemcode = Column(String(80), primary_key=True, unique=True)
opsystemname = Column(String(80))
opsystemversion = Column(String(80))
mfgcode = Column(String(80))
class ProdRecord(Base):
__tablename__ = 'prodrecord'
productcode = Column(Integer, ForeignKey('filerecord.productcode'), primary_key=True)
productname = Column(String(80))
productversion = Column(String(80))
opsystemcode = Column(String(50), ForeignKey('osrecord.opsystemcode'), primary_key=True)
mfgcode = Column(String(50), ForeignKey('mfgrecord.mfgcode'), primary_key=True)
language = Column(String(80))
applicationtype = Column(String(80))
__table_args__ = (UniqueConstraint
(productcode, opsystemcode, mfgcode),)
if __name__ == "__main__":
db_string = "postgres://postgres:Drpepper1#localhost:5432/project"
engine = create_engine(db_string)
Base.metadata.create_all(engine)

Obviously #univerio's comment above solved the problem, but that solution is not valid in a production setting--where dropping all the tables is simply not an option. One of the popular (and incredibly powerful) ways of managing a database, and the accompanying migrations that follow, is by using Alembic. It was written by the same guy who wrote SQLAlchemy, and I cannot recommend it enough. Here are a few more articles on that same topic:
https://www.compose.com/articles/schema-migrations-with-alembic-python-and-postgresql/
https://realpython.com/blog/python/flask-by-example-part-2-postgres-sqlalchemy-and-alembic/

Related

Django student here: I'm I getting a ValueError when creating a superuser using a custom made User class

I am working on a project that requires one to only create an account if their other details such as username are already in the database.
For this I created a custom user class named Account and linked the username field through a OneToOne relationship to the Reg No in the Student class.
I manually prepopulated the database with a single record so as to be able to create a superuser, because the creation of an account would require an existing Student record. But I am getting a value error on the terminal like so:
(djangoenv) myMachine:~/Django9/eschool$ python3 manage.py createsuperuser
Email: ********#**.me
Username (Student.School_ID): 1
Password:
Password (again):
Traceback (most recent call last):
File "/home/biketi21/Django9/eschool/manage.py", line 22, in <module>
main()
File "/home/biketi21/Django9/eschool/manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
utility.execute()
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/core/management/__init__.py", line 413, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/core/management/base.py", line 354, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 79, in execute
return super().execute(*args, **options)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/core/management/base.py", line 398, in execute
output = self.handle(*args, **options)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/contrib/auth/management/commands/createsuperuser.py", line 157, in handle
validate_password(password2, self.UserModel(**fake_user_data))
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/db/models/base.py", line 485, in __init__
_setattr(self, field.name, rel_obj)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 310, in __set__
super().__set__(instance, value)
File "/home/biketi21/anaconda3/envs/djangoenv/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py", line 215, in __set__
raise ValueError(
ValueError: Cannot assign "1": "Account.username" must be a "Student" instance.
Below is my Models.py:
I'm using MySQL Database as the backend.
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
# Create your models here.
class Student(models.Model):
FirstName = models.CharField(max_length=50)
Surname = models.CharField(max_length=50)
Reg_No = models.CharField(max_length=11, unique=True)
National_ID = models.IntegerField(unique=True)
School_ID = models.AutoField(primary_key=True)
County = models.CharField(max_length=20)
Sub_County = models.CharField(max_length=50)
Course_Title = models.ForeignKey("Course", on_delete=models.CASCADE)
Admission_Date = models.DateField(auto_now=True)
def __str__(self):
return str(self.Reg_No)
class Course(models.Model):
Course_Title = models.CharField(max_length=100)
Course_ID = models.CharField(max_length=10)
Number_of_Semesters = models.IntegerField()
Total_Cost_of_Course = models.IntegerField()
def __str__(self):
return str(self.Course_ID)
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError('Users must have an email address.')
if not username:
raise ValueError('Users must have a username.')
user = self.model(
email=self.normalize_email(email),
username=username,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
username=username,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name='email', max_length=60, unique=True)
username = models.OneToOneField(Student, unique=True, on_delete=models.CASCADE)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = MyAccountManager()
def __str__(self):
return self.username
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
Any help in solving this problem is appreciated.

Graphene with SQLAlchemy results in "AssertionError: You need to pass a valid SQLAlchemy Model" with no additional information as to what is wrong

I'm trying to build a FastApi app with a Postgres db and am using SQLAlchemy and Alembic (for handling DB modeling and migrations respectively). And this will be a GraphQL API, so I'm using graphene for that.
Here are my files:-
models.py
from sqlalchemy import Column, DateTime, Integer, Enum, String, Boolean, JSON
from sqlalchemy.orm import column_property, validates, relationship
from sqlalchemy.sql.schema import ForeignKey
from sqlalchemy.sql import func
from config import DEFAULT_AVATARS
from database import Base
import enum
# Status Choices for User's Membership Status
class MembershipStatusChoice(enum.Enum):
UI = 'UNINITIALIZED'
PE = 'PENDINIG'
AP = 'APPROVED'
SU = 'SUSPENDED'
# End of Status Choices
# Start of setting up Course status choices
class CourseStatusChoice(enum.Enum):
DR = 'DRAFT'
PU = 'PUBLISHED'
AR = 'ARCHIVED'
# End of status choices
class AnnouncementsSeen(Base):
__tablename__ = 'announcements_seen'
id = Column(Integer, primary_key=True)
user_id = relationship('User', backref='user')
announcement_id = Column(ForeignKey('announcement.id'), index=True)
class CompletedCourses(Base):
__tablename__ = 'completed_courses'
id = Column(Integer, primary_key=True)
participant_id = relationship('User', backref='user')
course_id = Column(ForeignKey('course.id'), index=True)
class CompletedChapters(Base):
__tablename__ = 'completed_chapters'
id = Column(Integer, primary_key=True)
participant_id = relationship('User', backref='user')
chapter_id = Column(ForeignKey('chapter.id'), index=True)
course_id = Column(ForeignKey('course.id'))
status = Column(Enum(CourseStatusChoice))
scored_points = Column(Integer, default=0)
total_points = Column(Integer, default=0)
percentage = Column(Integer, default=0)
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True, index=True)
firstname = Column(String(50), default="Uninitialized", nullable=False)
lastname = Column(String(50), default="User", nullable=False)
name = column_property(firstname + " " + lastname)
email = Column(String(255), nullable=False, unique=True)
avatar = Column(String(250), nullable=False, default=DEFAULT_AVATARS['USER'])
institution_id = Column(Integer, ForeignKey('institution.id'), nullable=False)
role = Column(String, ForeignKey('user_role.name'), nullable=True)
title = Column(String(150), nullable=True)
bio = Column(String(300), nullable=True)
#validates('email')
def validate_email(self, key, email):
if isinstance(email, str):
return email.lower()
return email
membership_status = Column(Enum(MembershipStatusChoice), nullable=False, default='SU')
chapters = relationship('CompletedChapters', backref='completed_chapters')
courses = relationship('CompletedCourses', backref='completed_courses')
announcements = relationship("AnnouncementsSeen", backref='announcements_seen')
searchField = Column(String(1000))
active = Column(Boolean, default=True)
created_at = Column(
DateTime(timezone=True),
server_default=func.now()
)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
server_onupdate=func.now()
)
class UserRole(Base):
__tablename__ = 'user_role'
name = Column(String(50), primary_key=True, unique=True, index=True)
description = Column(String(500))
priority = Column(Integer) # Lower the number higher the priority
def default_permissions():
return {}
permissions = Column(JSON, default=default_permissions)
searchField = Column(String(600))
active = Column(Boolean, default=True)
created_at = Column(
DateTime(timezone=True),
server_default=func.now()
)
updated_at = Column(
DateTime(timezone=True),
server_default=func.now(),
server_onupdate=func.now()
)
schemas.py
from graphene_sqlalchemy import SQLAlchemyObjectType
from pydantic import BaseModel
from models import User
class UserSchema(BaseModel):
title: str
content: str
class UserModel(SQLAlchemyObjectType):
class Meta:
model = User
main.py
import graphene
from models import User
from schemas import UserModel
from database import db_session
db = db_session.session_factory()
class Query(graphene.ObjectType):
all_users = graphene.List(UserModel)
user_by_id = graphene.Field(UserModel, user_id=graphene.Int(required=True))
def resolve_all_users(self, info):
query = UserModel.get_query(info)
return query.all()
def resolve_user_by_id(self, info, user_id):
return db.query(User).filter(User.id == user_id).first()
app = FastAPI()
app.add_route("/graphql", GraphQLApp(schema=graphene.Schema(query=Query)))
I have this all in a docker. So I use these commands to make the migrations and run the app:-
"makemigrations": "docker-compose run app alembic revision --autogenerate -m 'New Migration'",
"migrate": "docker-compose run app alembic upgrade head",
The docker command that runs the app is uvicorn main:app --host 0.0.0.0 --port 8000 --reload
But when I make the migrations and migrate and start the app, this is what I get:-
app | INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
app | INFO: Started reloader process [1] using statreload
app | Process SpawnProcess-1:
app | Traceback (most recent call last):
app | File "/usr/local/lib/python3.8/multiprocessing/process.py", line 315, in _bootstrap
app | self.run()
app | File "/usr/local/lib/python3.8/multiprocessing/process.py", line 108, in run
app | self._target(*self._args, **self._kwargs)
app | File "/usr/local/lib/python3.8/site-packages/uvicorn/subprocess.py", line 76, in subprocess_started
app | target(sockets=sockets)
app | File "/usr/local/lib/python3.8/site-packages/uvicorn/server.py", line 50, in run
app | loop.run_until_complete(self.serve(sockets=sockets))
app | File "/usr/local/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
app | return future.result()
app | File "/usr/local/lib/python3.8/site-packages/uvicorn/server.py", line 57, in serve
app | config.load()
app | File "/usr/local/lib/python3.8/site-packages/uvicorn/config.py", line 318, in load
app | self.loaded_app = import_from_string(self.app)
app | File "/usr/local/lib/python3.8/site-packages/uvicorn/importer.py", line 22, in import_from_string
app | module = importlib.import_module(module_str)
app | File "/usr/local/lib/python3.8/importlib/__init__.py", line 127, in import_module
app | return _bootstrap._gcd_import(name[level:], package, level)
app | File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
app | File "<frozen importlib._bootstrap>", line 991, in _find_and_load
app | File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
app | File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
app | File "<frozen importlib._bootstrap_external>", line 843, in exec_module
app | File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
app | File "/app/api/./main.py", line 6, in <module>
app | from schemas import UserModel, UserSchema
app | File "/app/api/./schemas.py", line 12, in <module>
app | class UserModel(SQLAlchemyObjectType):
app | File "/usr/local/lib/python3.8/site-packages/graphene/utils/subclass_with_meta.py", line 52, in __init_subclass__
app | super_class.__init_subclass_with_meta__(**options)
app | File "/usr/local/lib/python3.8/site-packages/graphene_sqlalchemy/types.py", line 210, in __init_subclass_with_meta__
app | assert is_mapped_class(model), (
app | AssertionError: You need to pass a valid SQLAlchemy Model in UserModel.Meta, received "<class 'models.User'>".
I found these GitHub issues that indicate that there may be silent errors that sqlalchemy is giving off that are not showing up in the stack trace. But I'm not able to use that info to precisely pinpoint what is wrong with my model configurations. I tried working out the many to many relationships there and even removing them to see if it fixes it. But it keeps showing the same error. Need help!
Hi I think the error is coming because in main.py you haven't called the meta data.
class User(SQLAlchemyObjectType):
"""
User Connection
"""
class Meta:
"""setting up connection for flow_details"""
model = models.User
# use `exclude_fields` to exclude specific fields ie "id"
interfaces = (relay.Node,)
# fields = "__all__"
class Query(graphene.ObjectType):
node = relay.Node.Field()
get_user=SQLAlchemyConnectionField(User.connection)
import from graphene import relay as well. You need to set a connection first. When you are calling the resolver its not getting any Sqlalchemyobject to fetch data from

sqlalchemy ORM : how to declare a table class that contains multiple key?

I'm a newbie in Sqlalchemy.
I have a table with multiple key in column USERNAME.
This is what I've done in my model.
Model:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root#localhost/admin'
db = SQLAlchemy(app)
class RADUSAGE(db.Model):
__tablename__ = 'RADUSAGE'
USERNAME = db.Column(db.String(513))
AGE = db.Column(db.Integer)
def __init__(self, USERNAME, AGE):
self.USERNAME = USERNAME
self.AGE = AGE
def __repr__(self):
return '<RADUSAGE %r>' % self.USERNAME
But I got an error:
File "/Users/admin/rad_env/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 530, in map
**self.mapper_args
File "<string>", line 2, in mapper
File "/Users/admin/rad_env/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 677, in __init__
self._configure_pks()
File "/Users/admin/rad_env/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1277, in _configure_pks
(self, self.mapped_table.description))
sqlalchemy.exc.ArgumentError: Mapper Mapper|RADUSAGE|RADUSAGE could not assemble any primary key columns for mapped table 'RADUSAGE'
How can I declare this table class that contains multiple key in sqlalchemy? Hope someone can help me. Thanks in advance.
You should be able to specify primary_key=true in your mapping for each PK column:
USERNAME = db.Column(db.String(513), primary_key=True)
AGE = db.Column(db.Integer, primary_key=True)
Did you try that?

Why is Flask-Admin throwing this exception when attempting to edit a model?

The exception is AttributeError: 'StringField' object has no attribute 'wrap_formdata' and it seems to only happen when I go to create or edit either of the following two models from the Flask-Admin dashboard:
class Experiment(db.Model):
id = db.Column(db.Integer, primary_key=True)
property_id = db.Column(db.Integer,
db.ForeignKey('property.id'),
index=True,
nullable=False)
name = db.Column(db.String, nullable=False)
start_date = db.Column(db.DateTime, nullable=True)
end_date = db.Column(db.DateTime, nullable=True)
status = db.Column(db.String, nullable=False, default='Draft')
title = db.Column(db.String)
meta = db.Column(db.String)
seed_uri = db.Column(db.String)
targets = db.Column(postgresql.JSON)
variations_json = db.Column(postgresql.JSON)
variations = db.relationship('ExperimentVariation',
backref='experiment',
cascade='save-update, merge, delete')
def __repr__(self):
repr_fmt = '<Experiment {id}, {property_id} {name}>'
return repr_fmt.format(id=self.id,
property_id=self.property_id,
name=self.name)
class ExperimentVariation(db.Model):
id = db.Column(db.Integer, primary_key=True)
experiment_id = db.Column(db.Integer,
db.ForeignKey('experiment.id'),
index=True,
nullable=False)
name = db.Column(db.String, nullable=False)
title = db.Column(db.String)
meta = db.Column(db.String)
def __repr__(self):
repr_fmt = '<ExperimentVariation {id}, {experiment_id} {name}>'
return repr_fmt.format(id=self.id,
experiment_id=self.experiment_id,
name=self.name)
I'm wondering if there's some complication with the relationships. I can provide the Property model if that helps, but in a nutshell most of that model is just providing relationships between other models including the Experiment model.
A quick Google doesn't appear to turn up similar issues. More than likely I'm overlooking something obvious or perhaps not fully grokking the relationship API.
Also I've included the full traceback below for clarity:
ERROR [ranksci] Exception on /admin/experiment/edit/ [GET]
Traceback (most recent call last):
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask_admin/base.py", line 69, in inner
return self._run_view(f, *args, **kwargs)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask_admin/base.py", line 368, in _run_view
return fn(self, *args, **kwargs)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask_admin/model/base.py", line 1969, in edit_view
form = self.edit_form(obj=model)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask_admin/model/base.py", line 1256, in edit_form
return self._edit_form_class(get_form_data(), obj=obj)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/wtforms/form.py", line 212, in __call__
return type.__call__(cls, *args, **kwargs)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/flask_admin/form/__init__.py", line 16, in __init__
super(BaseForm, self).__init__(formdata=formdata, obj=obj, prefix=prefix, **kwargs)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/wtforms/form.py", line 278, in __init__
self.process(formdata, obj, data=data, **kwargs)
File "/Users/max/Documents/projects/ranksci-app/virtualenv/lib/python2.7/site-packages/wtforms/form.py", line 119, in process
formdata = self.meta.wrap_formdata(self, formdata)
AttributeError: 'StringField' object has no attribute 'wrap_formdata'
I've figured out the root cause of this problem: Flask-Admin constructs a form class, which by default subclasses a WTForm's Form class, from each SQLA model. This is all well and good unless one of your columns matches one of the arguments the WTForm's constructor takes, for instance meta.
The logic for constructing said classes is here. I'm not completely sure what the correct fix for this is, however it does seem like a situation Flask-Admin needs to handle either technically or socially. For instance, it would be handy to know ahead of time that meta shouldn't be used as a column name since this problem will occur.
It's worth pointing out that the following variables are also accepted by the WTForm's Form constructor and thus should probably be avoided as well: formdata, obj, prefix, and data.
A technical solution to this problem might be to construct a set of these variable names and then explicitly check for them when creating the model forms in the above Flask-Admin code. Then a warning of some kind could be generated or the name variable could be altered such that it was prefixed with _ or some such. This isn't a perfect solution because of course WTForms could change its API in the future.

Issues in flask-restless due to sqlalchemy.db.Boolean

I have just moved from flask-sqlalchemy to just sqlalchemy. And I have started getting below issue.
Issue 1 :
I have two models
class Candidate(db.Model):
__tablename__ = 'candidate'
id = db.Column(db.Integer, primary_key=True)
country_id = db.Column(db.Integer, db.ForeignKey('country.id'), nullable=True)
first_name = db.Column(db.String(100), nullable=True)
last_name = db.Column(db.String(100))
email = db.Column(db.String(255), nullable=False, unique=True)
is_deleted = db.Column(db.Boolean, nullable=False, default=False, server_default=db.text("false"))
class Country(db.Model):
__tablename__ = 'country'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(150), nullable=False, unique=True)
created_on = db.Column(db.DateTime, default=_get_date_time)
modified_on = db.Column(db.TIMESTAMP, onupdate=_get_date_time, nullable=False, server_default=db.text("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP"))
is_deleted = db.Column(db.Boolean, nullable=False, default=False, server_default=db.text("false"))
I created tables in my students db using alembic. The migration file it generated looks like
# ... snip ...
op.create_table('country',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('name', sa.String(length=150), nullable=False),
sa.Column('created_on', sa.DateTime(), nullable=True),
sa.Column('modified_on', sa.TIMESTAMP(), server_default=sa.text(u'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), nullable=False),
sa.Column('is_deleted', sa.Boolean(), server_default=sa.text(u'false'), nullable=False),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('name')
)
op.create_table('candidate',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('first_name', sa.String(length=100), nullable=True),
sa.Column('last_name', sa.String(length=100), nullable=True),
sa.Column('country_id', sa.Integer(), nullable=True),
sa.Column('email', sa.String(length=255), nullable=False),
sa.Column('is_deleted', sa.Boolean(), server_default=sa.text(u'false'), nullable=False),
sa.ForeignKeyConstraint(['country_id'], ['country.id'], ),
sa.UniqueConstraint('email'),
)
I loaded data from the mysqldump that I had created when I was using falsk-sqlalchemy.
INSERT INTO `country` VALUES (1,'India','2015-05-16 16:51:30','2015-05-16 11:21:30',0),(2,'Australia','2015-05-16 17:10:33','2015-05-16 11:40:33',0);
INSERT INTO `candidate` VALUES (1,1,'Jon','Snow','jon-snow#got.com',0);
Issue : But mysqldump should have put false in place of is_deleted, don't you think? Also note that when I manually replace 0 by false in mysqldump for is_deleted, I don't fall into Issue 2.
Issue 2 :
I use flask restless API layer to do CRUD operations.
# ... snip ...
manager = flask.ext.restless.APIManager(app, session=mysession)
manager.create_api(Country, methods=['GET'])
manager.create_api(Candidate, methods=['GET','POST'])
# ... snip ...
Issue : When I hit /candidate api, I get below error. It was working fine with flask-sqlalchemy
ValueError: int_to_boolean only accepts None, 0 or 1
Traceback for Issue 2
Traceback (most recent call last):
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restful/__init__.py", line 270, in error_router
return original_handler(e)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_cors/extension.py", line 110, in wrapped_function
return cors_after_request(app.make_response(f(*args, **kwargs)))
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 157, in decorator
return func(*args, **kw)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/mimerender.py", line 229, in wrapper
result = target(*args, **kwargs)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/views.py", line 84, in view
return self.dispatch_request(*args, **kwargs)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask/views.py", line 149, in dispatch_request
return meth(*args, **kwargs)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 189, in wrapped
return func(*args, **kw)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 1239, in get
return self._search()
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 1194, in _search
result = self._paginated(result, deep)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/flask_restless/views.py", line 981, in _paginated
for x in instances[start:end]]
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2228, in __getitem__
return list(res)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 73, in instances
rows = [process[0](row, None) for row in fetch]
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 455, in _instance
populate_state(state, dict_, row, isnew, only_load_props)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 305, in populate_state
populator(state, dict_, row)
File "/home/hussain/workspace/api/lib/python2.7/site-packages/sqlalchemy/orm/strategies.py", line 169, in fetch_col
dict_[key] = row[col]
ValueError: int_to_boolean only accepts None, 0 or 1
How do I tackle this issue? Please help me out.