Sql Alchemy Error When Moving Colums To Init Method
Solution 1:
SQLAlchemy's declarative base mechanism establishes a Python metaclass. That means that SQLAlchemy will specially process the definition of your class.
The purpose of that processing is to construct an sqlalchemy.orm.Mapper
for each mapped class. That mapper represents the mapping between your database tables and your class.
In order to do that, SQLAlchemy generally needs to be able to find a primary key. This is required in order to define the identity associated with each mapped instance, so that mapped objects can be cached/found in sessions. That at least needs to be possible when your mapped class is constructed.
That means that you need to define the column of at least the primary key on the class.
Other answers have explained that much, although I think I've provided a bit more detail.
There is a more fundamental problem though.
id = Column(Integer, primary_key = True)
is of course a call to the Column function you import from SQLAlchemy. However, the return from the Column
function is a schema item. This schema item is converted by declarative base into a descriptor similar to the kind of descriptor that the property
decorator gives you. Such descriptors only work on a class, not an instance of that class.
Let's say I have a class mapped to a table called User
and an instance of that user in a variable bob
.
User.id
Is a description of the identity column. However
bob.id
is the number that identifies Bob in the users table. That is, columns aren't intended to be assigned to members of self, they are intended to be assigned to classes.
So:
You need to have at least the primary key column on your class when you define it.
It's generally a good idea to have all your Columns there.
You can add a
Column
definition to your class later, although things will only work if you arrange for that column to get into your tableIt's always wrong to add a
Column
to an instance of a mapped class.self.x = Column
is always wrong.
Solution 2:
The SQLAlchemy ORM (almost) always requires a primary key. You have indeed defined one inside your __init__()
function. The problem is that __init__()
doesn't get called until you create a User
object. I assume you create your database before a User
object ever gets created. Thus as far as the SQLAlchemy ORM is concerned, a primary key does not exist for User
(nor any of the other attributes declared inside __init__
).
The solution, as I think you already found from your last line, is to declare them as class attributes where as soon you do something like from models import User
the attributes are defined and SQLAlchemy can properly build your User
table.
class User(Base):
id =Column(Integer, primary_key=True)
first_name =Column(String)
last_name =Column(String)
email_id =Column(String)
mobile =Column(String)
username =Column(String)
hashed_password =Column(String)
def set_first_name(self, first_name):
self.first_name = first_name
...
Solution 3:
You don't have to declare the column definitions inside the __init__()
function. Change your class definition to something like this and it should work:
class User(Base):
__tablename__ = "user"
id =Column(Integer, primary_key=True)
first_name =Column(String)
last_name =Column(String)
email_id =Column(String)
mobile =Column(String)
username =Column(String)
hashed_password =Column(String)
Post a Comment for "Sql Alchemy Error When Moving Colums To Init Method"