SQLAlchemy KeyError when using both an index and a UniqueConstraint - python

When I include both a UniqueConstraint and Index in my table definition I get a KeyError. However, the error goes away if I specify UniqueConstraint alone or Index alone. I'm using SQLAlchemy==1.3.8.
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.schema import Index, UniqueConstraint
Base = declarative_base()
class A(Base):
__tablename__ = 'table_a'
id = Column(Integer, primary_key=True)
a = Column(String(32))
b = Column(String(32))
UniqueConstraint('a_unique_constraint', A.a, A.b)
Index('a_index', A.a, A.b)
Traceback (most recent call last):
File "/Users/ryan.zotti/Documents/repos/recommendations/orm_example.py", line 14, in
UniqueConstraint('a_unique_constraint', A.a, A.b)
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/sql/schema.py", line 2870, in init
self, *columns, _autoattach=_autoattach, _column_flag=_column_flag
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/sql/schema.py", line 2762, in init
self._check_attach()
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/sql/schema.py", line 2818, in _check_attach
self._set_parent_with_dispatch(tables.pop())
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/sql/base.py", line 456, in _set_parent_with_dispatch
self._set_parent(parent)
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/sql/schema.py", line 2881, in _set_parent
ColumnCollectionMixin._set_parent(self, table)
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/sql/schema.py", line 2838, in _set_parent
for col in self._col_expressions(table):
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/sql/schema.py", line 2834, in _col_expressions
for col in self._pending_colargs
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/sql/schema.py", line 2834, in
for col in self._pending_colargs
File "/anaconda3/envs/recommendations/lib/python3.7/site-packages/sqlalchemy/util/_collections.py", line 194, in getitem
return self._data[key]
KeyError: 'a_unique_constraint'

Related

AttributeError: type object 'Page' has no attribute 'query'

Trying to add a custom batch action but I keep getting this error, I've added my imports into the code to show what i'm importing, this file is separate to my model file, this is my views.py file
Views.py
import flask_admin as admin
import textwrap
from flask_admin.actions import action
from flask_admin.contrib import sqla
from flask_admin.contrib.sqla import ModelView
from flask_admin.contrib.sqla.filters import FilterEqual
from app.models import FileRegister, FileRegisterStatus
from app import app, db, models
class PageView(ModelView):
#action("active", "Active", 'Are you sure you want to active selected pages?')
def action_active(self, ids):
try:
query = Page.query.filter(Page.id.in_(ids))
count = 0
for page in query.all():
page.is_active = True
count += 1
flash(ngettext('Page was successfully activated.',
'%(count)s pages were successfully activated.',
count,
count=count))
except Exception as ex:
if not self.handle_view_exception(ex):
raise
flash(gettext('Failed to active pages. %(error)s', error=str(ex)), 'error')
models.py
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Boolean, TIMESTAMP, ForeignKey
import datetime
Base = declarative_base()
class Page(Base):
__tablename__ = 'page'
id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
page_name= Column(String(500), index=True, nullable=False)
is_page_active= Column(Boolean())
def __init__(self, page_name, is_page_active):
self.page_name= page_name
self.is_page_active= is_page_active
def __unicode__(self):
return self.page_name
This is the Traceback (most recent call last) I get after running the code, ,I think its because I call query() on my mapped classes instead of the session?
Traceback (most recent call last):
File "C:\page\env\lib\site-packages\flask\app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "C:\page\env\lib\site-packages\flask\app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "C:\page\env\lib\site-packages\flask\app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\page\env\lib\site-packages\flask\app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "C:\page\env\lib\site-packages\flask\app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\page\env\lib\site-packages\flask\app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\page\env\lib\site-packages\flask\app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "C:\page\env\lib\site-packages\flask\app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\page\flask_admin\base.py", line 69, in inner
return self._run_view(f, *args, **kwargs)
File "C:\page\flask_admin\base.py", line 368, in _run_view
return fn(self, *args, **kwargs)
File "c:\page\flask_admin\model\base.py", line 2145, in action_view
return self.handle_action()
File "C:\page\flask_admin\actions.py", line 117, in handle_action
response = handler[0](ids)
File "C:\page\app\views.py", line 28, in action_active
if not self.handle_view_exception(ex):
File "c:\page\flask_admin\contrib\sqla\view.py", line 1060, in handle_view_exception
return super(ModelView, self).handle_view_exception(exc)
File "C:\page\app\views.py", line 16, in action_active
query = Page.query.filter(Page.active_ind.in_(ids))
AttributeError: type object 'Page' has no attribute 'query'
Since I was using a declarative model, this was the fix. This goes into the models.py file
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine('databaselinkgoeshere', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

session is already flushing when I use #observes

I'm building a flask app and I want to use sqlalchemy observers to update a shipment status once all products inside that shipment become available.
Here's my datamodel:
from app import db
from sqlalchemy_utils import observes
class Shipment(db.Model):
__tablename__ = 'shipment'
id = db.Column(db.Integer, primary_key=True)
products = db.relationship('Product', backref='shipment', lazy='dynamic')
all_products_ready = db.Column(db.Boolean)
#observes('products')
def product_observer(self, products):
for p in self.products:
if p.status != 'ready':
self.all_products_ready = False
return False
self.all_products_ready = True
return True
class Product(db.Model):
__tablename__ = 'product'
id = db.Column(db.Integer, primary_key=True)
shipment_id = db.Column(db.Integer, db.ForeignKey('shipment.id'))
status = db.Column(db.String(120), index=True)
And here is some code I run to test it:
shipment = models.Shipment(products=[models.Product(status='ready'), models.Product(status='not_ready')])
db.session.add(shipment)
db.session.commit()
print(shipment.all_products_ready)
When I run this code I get an InvalidRequestError: Session is already flushing.
Here is the stack trace:
Traceback (most recent call last):
File "test.py", line 5, in <module>
db.session.commit()
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\scoping.py",
line 150, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\session.py",
line 788, in commit
self.transaction.commit()
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\session.py",
line 384, in commit
self._prepare_impl()
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\session.py",
line 364, in _prepare_impl
self.session.flush()
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\session.py",
line 1985, in flush
self._flush(objects)
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\session.py",
line 2012, in _flush
self.dispatch.before_flush(self, flush_context, objects)
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\event\attr.py", l
ine 221, in __call__
fn(*args, **kw)
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy_utils\observer.py
", line 272, in invoke_callbacks
for (root_obj, func, objects) in args:
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy_utils\observer.py
", line 252, in gather_callback_args
lambda obj: obj not in session.deleted
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy_utils\functions\o
rm.py", line 741, in getdotattr
last = [v for v in last if condition(v)]
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\dynamic.py",
line 245, in __iter__
sess = self.session
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\dynamic.py",
line 237, in session
sess.flush()
File "U:\dev\observertest\flask\lib\site-packages\sqlalchemy\orm\session.py",
line 1979, in flush
raise sa_exc.InvalidRequestError("Session is already flushing")
sqlalchemy.exc.InvalidRequestError: Session is already flushing
How can I use my models without getting this error?
I'm not completely sure why, but I think loading the relations using dynamic is causing problems here. In this line:
products = db.relationship('Product', backref='shipment', lazy='dynamic')
you need to change the lazy parameter to select instead of dynamic (or you can take out the lazy parameter alltogether as select is its default).
See the sqlalchemy reference for all the available options.

Cant change class on SQLAlchemy

Hello I am trying to change a class in SQLAlchemy because it giving me an error, the error is:
File "<string>", line 2, in __init__
File "C:\Python34\lib\site-packages\sqlalchemy\orm\instrumentation.py", line 324, in _new_state_if_none
state = self._state_constructor(instance, self)
File "C:\Python34\lib\site-packages\sqlalchemy\util\langhelpers.py", line 725, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\instrumentation.py", line 158, in _state_constructor
self.dispatch.first_init(self, self.class_)
File "C:\Python34\lib\site-packages\sqlalchemy\event\attr.py", line 260, in __call__
fn(*args, **kw)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\mapper.py", line 2693, in _event_on_first_init
configure_mappers()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\mapper.py", line 2589, in configure_mappers
mapper._post_configure_properties()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\mapper.py", line 1694, in _post_configure_properties
prop.init()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\interfaces.py", line 144, in init
self.do_init()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\relationships.py", line 1549, in do_init
self._process_dependent_arguments()
File "C:\Python34\lib\site-packages\sqlalchemy\orm\relationships.py", line 1605, in _process_dependent_arguments
self.target = self.mapper.mapped_table
File "C:\Python34\lib\site-packages\sqlalchemy\util\langhelpers.py", line 725, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "C:\Python34\lib\site-packages\sqlalchemy\orm\relationships.py", line 1535, in mapper
% (self.key, type(argument)))
sqlalchemy.exc.ArgumentError: relationship 'prod_comm_rel' expects a class or a mapper argument (received: <class 'sqlalchemy.sql.schema.Column'>)
But it never change the error keeps comming, this is my class:
class Product(Base):
__tablename__="xxxxxx_reg"
__table_args__ = {"useexisting": True}
id = Column("id",BIGINT, primary_key=True)
name = Column("_name",Text, nullable=False)
code = Column("code", BIGINT, unique=True)
status = Column("status",BIGINT, ForeignKey(Status.code),nullable=False)
description = Column("description",Text, nullable=False)
avatar = Column("avatar", Text, nullable=False)
type = Column("_type",BIGINT, ForeignKey(Type.id),nullable=False)
price = Column("price",Numeric(20,2),nullable=False)
costs = Column("costs",Numeric(20,2),default=0.00)
commCode = Column("commerce", BIGINT, ForeignKey(Commerce.code), nullable=False)
#Relation
prod_status_rel = relationship(Status, backref=backref("Product"))
prod_type_rel = relationship(Type, backref=backref("Product"))
prod_comm_rel = relationship(Commerce, backref=backref("Product"))
def __repr__(self):
return "<Product(id='%s', name='%s', status='%s', description='%s', " \
"type='%s', price='%s', costs='%s', code='%s',commerce='%s')>"%(self.id, self.name,
self.status,self.description,
self.type, self.price, self.costs, self.code, self.commCode)
metadata = MetaData()
product_tbl = Table(__tablename__, metadata,id,name,status,description, type,price, costs, code, commCode)
engine = conection().conORM()
metadata.create_all(engine)
How can I fix this code, because I made the change and when I run the class alone It works, the problem is when i try to run it with the other parts of the codes

How to create self-referencing EndpointsModel

I'm trying to create following self-referencing EndpointsModel (the trick with _fix_up_properties() is taken from here: https://groups.google.com/forum/#!topic/appengine-ndb-discuss/1FmgEVK7JNM):
class EventFieldSchema(EndpointsModel):
name = ndb.StringProperty(required=True)
type = msgprop.EnumProperty(EventType, required=True)
EventFieldSchema.nested_fields = ndb.LocalStructuredProperty(EventFieldSchema,repeated=True)
EventFieldSchema._fix_up_properties()
This works for datastore model, but unfortunately, the nested_fields field won't be included into ProtoRPC message.
I've tried to manually specify message fields schema, by adding at the end following line:
EventFieldSchema._message_fields_schema = ('name', 'type', 'nested_fields')
but then app-engine fails, going into a loop, trying turn EventFieldSchema into ProtoRPC field:
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 240, in Handle
handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
handler, path, err = LoadObject(self._handler)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/runtime/wsgi.py", line 85, in LoadObject
obj = __import__(path[0])
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/main.py", line 3, in <module>
from er.api.event import EventRegistryApi
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/er/api/event.py", line 17, in <module>
class EventRegistryApi(remote.Service):
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/er/api/event.py", line 23, in EventRegistryApi
name='%s.insert' % RESOURCE_NAME)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/protorpc-1.0/protorpc/util.py", line 170, in positional_wrapper
return wrapped(*args, **kwargs)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 1359, in method
kwargs[REQUEST_MESSAGE] = cls.ProtoModel(fields=request_fields)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 1031, in ProtoModel
allow_message_fields=allow_message_fields)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 969, in _MessageFields
proto_attr = to_proto(prop, field_index)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/utils.py", line 137, in StructuredPropertyToProto
property_proto = property_proto_method()
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 1031, in ProtoModel
allow_message_fields=allow_message_fields)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 969, in _MessageFields
proto_attr = to_proto(prop, field_index)
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/utils.py", line 137, in StructuredPropertyToProto
property_proto = property_proto_method()
File "/base/data/home/apps/s~project/eventregistry:dev.380885914276541023/endpoints_proto_datastore/ndb/model.py", line 1031, in ProtoModel
Is this a bug in EndpointsModel? What is the "proper" way of defining self-referencing EndpointsModels?
Having the same issue with self-referencing an EndpointsModel:
class UnitsProtoModel(EndpointsModel):
""" ProtoRPC Model for storing/retrieving a unit. """
_message_fields_schema = ('id', 'uic', 'parent_id', 'branch_id', 'name')
uic = ndb.StringProperty(required=True)
parent_id = ndb.StringProperty(required=True, default=None)
branch_id = ndb.StringProperty(required=True)
name = ndb.StringProperty(required=True)
abbreviated_name = ndb.StringProperty(default="")
flagged = ndb.BooleanProperty(default=False)
message = ndb.StringProperty(default="")
unit_created_at = ndb.DateTimeProperty(auto_now_add=True)
class UnitsCollection(EndpointsModel):
items = messages.MessageField(UnitsProtoModel, 1, repeated=True)
Error msg:
`File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine- default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/util.py", line 170, in positional_wrapper
return wrapped(*args, **kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/protorpc-1.0/protorpc/messages.py", line 1531, in init
raise FieldDefinitionError('Invalid message class: %s' % message_type)
FieldDefinitionError: Invalid message class:
UnitsProtoModel<abbreviated_name=StringProperty('abbreviated_name', default=''), branch_id=StringProperty('branch_id', required=True), flagged=BooleanProperty('flagged', default=False), message=StringProperty('message', default=''), name=StringProperty('name', required=True), owner=UserProperty('owner'), parent_id=StringProperty('parent_id', required=True), uic=StringProperty('uic', required=True), unit_created_at=DateTimeProperty('unit_created_at', auto_now_add=True)>`

SqlAlchemy , AttributeError: 'tuple' object has no attribute 'foreign_keys'

I have the following models to describe my database schema:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship, backref
import sqlalchemy.dialects.mysql as mysql
Base = declarative_base()
class Country(Base):
__tablename__ = 'countries'
__table_args__ = {
'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'
}
id = Column(mysql.TINYINT(unsigned=True), primary_key=True)
name = Column(mysql.VARCHAR(30), nullable=False)
competitions = relationship('Competition', backref='country')
class Competition(Base):
__tablename__ = 'competitions'
__table_args__ = {
'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'
}
id = Column(mysql.INTEGER(unsigned=True), primary_key=True)
name = Column(mysql.VARCHAR(30), nullable=False)
country_id = Column(mysql.TINYINT(unsigned=True), ForeignKey('countries.id'))
teams = relationship('Team', backref("competition") )
class Team(Base):
__tablename__ = 'teams'
__table_args__ = {
'mysql_engine': 'InnoDB',
'mysql_charset': 'utf8'
}
id = Column(mysql.INTEGER(unsigned=True), primary_key=True)
name = Column(mysql.VARCHAR(30), nullable=False)
competition_id = Column(mysql.INTEGER(unsigned=True), ForeignKey('competitions.id'), nullable=False)
and when I try to create a Team like:
team = Team()
I get the following traceback after the command above:
Traceback (most recent call last):
File "/home/giorgos/apps/Aptana_Studio_3/plugins/org.python.pydev_2.6.0.2012062121/pysrc/pydevd.py", line 1392, in <module>
debugger.run(setup['file'], None, None)
File "/home/giorgos/apps/Aptana_Studio_3/plugins/org.python.pydev_2.6.0.2012062121/pysrc/pydevd.py", line 1085, in run
pydev_imports.execfile(file, globals, locals) #execute the script
File "/home/giorgos/Documents/Aptana Studio 3 Workspace/BetPick/tests/insert_models.py", line 21, in <module>
team = Team()
File "<string>", line 2, in __init__
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", line 309, in _new_state_if_none
state = self._state_constructor(instance, self)
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 485, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", line 157, in _state_constructor
self.dispatch.first_init(self, self.class_)
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/event.py", line 291, in __call__
fn(*args, **kw)
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 2342, in _event_on_first_init
configure_mappers()
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 2258, in configure_mappers
mapper._post_configure_properties()
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1167, in _post_configure_properties
prop.init()
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/interfaces.py", line 128, in init
self.do_init()
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/properties.py", line 911, in do_init
self._determine_joins()
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/properties.py", line 1034, in _determine_joins
self.secondary)
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/orm/properties.py", line 1028, in _search_for_join
a_subset=mapper.local_table)
File "/home/giorgos/.virtualenvs/venv/local/lib/python2.7/site-packages/sqlalchemy/sql/util.py", line 262, in join_condition
b.foreign_keys,
AttributeError: 'tuple' object has no attribute 'foreign_keys'
what I am doing wrong ?
backref should be a keyword argument in your declaration of Competition.teams:
class Competition(Base):
# ...
teams = relationship('Team', backref="competition")
See the documentation on relationship. You can use a backref callable to configure the back reference explicitly, but you'd have to still use the backref keyword:
class Competition(Base):
# ...
teams = relationship('Team', backref=backref("competition", ... additional keywords ...))

Categories