nos nos - 2 months ago 8
Python Question

More succinct initialization for SQLAlchemy instance

It's my first attempt at sqlalchemy. I have a json file with my usr information and I would like to put them in a sqlite3 database file. It works but I find the instance initialization verbose since there are many columns in the table, as you can see below.

Is it possible to use a dictionary as input to initialize

User()
? Something like
a = User(usr)
?

import json
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///tutorial.db', echo=True)

Base = declarative_base()

class User(Base):
__tablename__ = 'users'

id = Column(Integer, primary_key=True)
bbs_id = Column(String)
name = Column(String)
sex = Column(String, nullable=False)
city = Column(String)
state = Column(String)
class_type = Column(String, nullable=False)
class_id = Column(String, nullable=False)
latitude = Column(Float)
longitude = Column(Float)

def __repr__(self):
return "<User(bbs_id='%s', name='%s'>" % (self.bbs_id, self.name)

Base.metadata.create_all(engine)


with open('mydata.json') as fin:
usrs = json.load(fin)

usr = usrs[0]

a = User(id=usr['id'], bbs_id=usr['bbs_id'], name=usr['name'])

Answer

If you know the property names in the JSON object match the column names of the Python model, you can just change:

a = User(id=usr['id'], bbs_id=usr['bbs_id'], name=usr['name'])

to:

a = User(**usr)

Double-star/dict unpacking passes each key/value pair of the dict as if it were an argument being passed by keyword. Since you didn't override __init__ for your model, it already allows and expects the arguments to be optional and passed by keyword, so this lines up perfectly.

Comments