How can I insert data with a python dict?
This doesn't work:
class Date(Base):
__tablename__ = 'dates'
__table_args__ = {'schema':'www'}
id = Column(Integer, primary_key=True)
salutation = Column(VARCHAR(1))
lastname = Column(VARCHAR(128))
firstname = Column(VARCHAR(50))
zipcode = Column(VARCHAR(255))
...
statement = dict({
'salutation': form.get('salutation'),
'lastname': form.get('lastname'),
'firstname': form.get('firstname'),
'zipcode': form.get('zipcode')
})
new_entry = Date(**statement)
session.add(new_entry)
session.commit()
This produces this error output
ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'dict'
[SQL: 'INSERT INTO ....
Related
I have the following model:
from marshmallow import Schema, fields
from server import db, ma, app
from sqlalchemy.ext.hybrid import hybrid_property
from .analysis import AnalysisSchema
class Category(db.Model):
__tablename__ = 'Categories'
__table_args__ = {'extend_existing': True}
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120), index=True, unique=True)
description = db.Column(db.Text, nullable=False)
img = db.Column(db.LargeBinary, nullable=False)
img_mimetype = db.Column(db.Text, nullable=False)
img_name = db.Column(db.Text, nullable=False)
analysis = db.relationship("Analysis", back_populates="category")
#property
def img_url(self):
return "/categories/" + str(self.id)
class CategorySchema(ma.SQLAlchemyAutoSchema):
class Meta:
# model = Category
fields = ("id", "name", "description", "img", "img_url", "analysis")
analysis = fields.Nested(AnalysisSchema, many=True)
class CreateCategorySchema(Schema):
name = fields.Str(required=True)
description = fields.Str(required=True)
class UpdateCategorySchema(Schema):
name = fields.Str(required=True)
description = fields.Str(required=False)
img_name = fields.Str(required=False)
img_mimetype = fields.Str(required=False)
I create a new category with the following code:
from flask import jsonify
from server import db, app
from ..models.category import (
Category,
CategorySchema,
CreateCategorySchema,
UpdateCategorySchema
)
def create_category(data):
app.logger.info('Create category invoked')
create_category_schema = CreateCategorySchema()
# errors = create_category_schema.validate(data)
errors = None
if errors:
app.logger.info('Found errors %s', errors)
return jsonify(errors), 400
name = Category.query.filter_by(name=data['name']).first()
app.logger.info('Name is %s', name)
if not name:
app.logger.info('Name not present')
category = Category(
name=data['name'],
description=data['description'],
img=data['img'],
img_name=data['img_name'],
img_mimetype=data['img_mimetype']
)
_save_category(category)
category_schema = CategorySchema()
response = category_schema.dump(category), 201
#response = jsonify('Category created'), 200
else:
response = jsonify('Category already exists'), 409
return response
def all_categories():
category_schema = CategorySchema(many=True, exclude=['img'])
categories = Category.query.all()
response = category_schema.dump(categories)
return jsonify(response), 20
def get_category(id):
return Category.query.filter_by(id=id).first()
def _save_category(category):
db.session.add(category)
db.session.commit()
If I try to invoke create_category I got the following error:
sqlalchemy.exc.DataError: (MySQLdb._exceptions.DataError) (1406, "Data too long for column 'img' at row 1")
[SQL: INSERT INTO `Categories` (name, description, img, img_mimetype, img_name) VALUES (%s, %s, %s, %s, %s)]
[parameters: ('test10', 'blah blah blah', b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00\x84\x00\x06\x06\x06\x06\x07\x06\x07\x08\x08\x07\n\x0b\n\x0b\n\x0f\x ... (371140 characters truncated) ... xe4\xd3\xc0\xe3\xcag\xaf\x17\xff\x00\xcc?\xfdD\xfe\x85\xc3\x91\x06\x07\x017#3\x93:\x7fE\xfe\xb3\xff\x00\xe9_\xff\x00\x04r-i\x86\xb7\xd6|#\xbf\xff\xd9', 'image/jpeg', 'WhatsApp_Image_2021-06-04_at_11.14.49_AM.jpeg')]
(Background on this error at: http://sqlalche.me/e/14/9h9h)
I don't understand why is trying to insert an image as a String if it is explicitly defined as a LargeBinary.
The solution can be found in the question comments. I had to increase the size of the Blob using the length attribute of SQLAlchemy.
I have a One2many field in inventory for product pack. And I want that all fields values of that One2many field should update in fields of One2many field in sales order, row and column wise. So, Anyone can help me.
My Python code is here:
class ProductTemplate(models.Model):
_inherit = "product.template"
product_pack = fields.One2many('product.pack', 'template_id', string='Product Pack', copy=True)
class ProductDesign(models.Model):
_description = 'Product Pack'
_name = "product.pack"
_rec_name = "product_id"
check_option = fields.Boolean('#')
template_id = fields.Many2one('product.template', string='Template', required="True", ondelete='cascade', index=True, copy=True)
product_id = fields.Many2one('product.product', string='Product', required="True", domain="[('is_pack','=',False)]")
services = fields.Many2one('gold.service')
qty = fields.Integer('Quantity', default=1)
Here in 'wizard' (One2many field table) i want to update all fields (row and column) of product_pack
class SalePackWizard(models.TransientModel):
_name = "sale.pack.wizard"
_description = "Sale Pack Wizard"
product_id = fields.Many2one('product.product', string="Product Pack", required=True, domain="[('is_pack','=',True)]")
wizard = fields.One2many('product.gold','service')
#api.onchange('product_id')
def _onchange_product_pack_name(self):
for w in self.product_id.product_pack:
for s in w:
print "s:", s.product_id.name, s.services, s.qty
r = []
print"r:", r
class ProductDesign(models.Model):
_description = 'Product Pack'
_name = "product.gold"
_rec_name = "products_ids"
service= fields.Many2one('product.val', string='Templates', required="True", ondelete='cascade', index=True, copy=True)
check_box = fields.Boolean('#')
products_ids = fields.Many2one('product.product', string='Product', required="True", domain="[('is_pack','=',False)]")
services = fields.Many2one('gold.service')
qtyy = fields.Integer('Quantity', default=1)
Problem Solved.
Here is the function code of problem:
wizard = fields.One2many('product.gold','service',change_default=True, default=_onchange_action_product_add)
#api.onchange('product_id')
def _onchange_action_product_add(self):
res = self.product_id.product_pack
r = []
value = {}
for var in self.product_id.product_pack:
print "var:::", var
for line in self.product_id.product_pack:
print "line:::", line , line.product_id, line.product_id.name, line.qty, line.services, line.id
data = {'products_ids': line.product_id.id,
'service':var.id, #many2one child field from one2many field
'services':line.services,
'qtyy': line.qty
}
print "data:", data
r.append((0, 0, data))
print "r.append", r.append, r
#return data
value.update(wizard=r)
return {'value': value}
i wrote a test case:
class MyTestCreateFilter(TestCase):
def test_createfilter(self):
test_filter = Filter(user_profile_id= 3,
keyword = 'ca',
industry = 'it',
zip_code = '50002',
distance = 30,
creation_date = datetime.date.today(),
last_run_date = datetime.date.today()
)
test_filter_form = FilterForm(instance=test_filter)
self.assertEqual(test_filter_form.is_valid(), False)#without data
test_filter_form = FilterForm({'user_profile_id':3,'keyword': 'ca','industry':'it','zip_code':'50002','distance':30,'creation_date': datetime.date.today(),
'last_run_date': datetime.date.today() }, instance=test_filter)
print test_filter_form.is_valid()
giving the error:
DoesNotExist: UserProfile matching query does not exist.
this is my form.how to write test case:
class FilterForm(forms.ModelForm):
class Meta:
model=Filter
exclude=('user_profile','creation_date','last_run_date')
widgets = {
'zip_code': forms.TextInput(attrs={'placeholder': "e.g. 20708"}),
}
def clean(self):
user_profile = self.instance.user_profile
keyword = self.cleaned_data.get("keyword")
if Filter.objects.filter(user_profile=user_profile, keyword=keyword).exclude(id=self.instance.id).count() > 0:
msg = u"A filter with that keyword already exists!"
self._errors["keyword"] = self.error_class([msg])
return self.cleaned_data
when i test the form giving this error:
user_profile = self.instance.user_profile
File "/usr/local/lib/python2.7/dist-packages/django/db/models/fields/related.py", line 343, in get
raise self.field.rel.to.DoesNotExist
DoesNotExist
how to solve it?
Simply creating model object will not create the record in the database.
Use .objects.create to create a record.
test_filter = Filter.objects.create(
user_profile_id= 3,
keyword = 'ca',
industry = 'it',
zip_code = '50002',
distance = 30,
creation_date = datetime.date.today(),
last_run_date = datetime.date.today()
)
or use save:
test_filter = Filter(...)
test_filter.save()
I have model "B" with many-to-many through Foreign Key:
class DManager(m.Manager):
def get_by_natural_key(self, name):
return self.get(name=name)
class D(m.Model):
objects = DManager()
id = m.AutoField(primary_key=True)
name = m.CharField(max_length=250, unique=True, null=False)
def natural_key(self):
return (self.name)
class A(m.Model):
id = m.IntegerField(unique=True, null=False, primary_key=True)
name = m.CharField(max_length=250, null=True)
class B(m.Model):
id = m.IntegerField(unique=True, null=False, primary_key=True)
name = m.CharField(max_length=250, null=True)
type = m.ForeignKey(D)
bs = m.ManyToManyField(A, through='C')
def natural_key(self):
## ?natural key for many-to-many?
return(self.name, self.type.natural_key(), ?????)
class C(m.Model):
a_id = m.ForeignKey(A)
b_id = m.ForeignKey(B)
I can get relation through foreign key (B-D), but I can't get relation from many-to-many (B-A) in my ajax.py:
....
if request.is_ajax():
aj_d = json.loads(request.body.decode('utf-8'))
raw_data = serializers.serialize(
'python', m.B.objects.filter(
bs__a_id__in=aj_d['data']).distinct(),
use_natural_foreign_keys=True)
output = json.dumps(raw_data)
return HttpResponse(output, content_type='application/json')
Maybe exist another way through values() for example. But I have problem with dumps list of dicts - "is not JSON serializable":
...
raw_data = m.B.objects.filter(
bs__a_id__in=aj_d['data']).distinct().values()
output = json.dumps(raw_data)
Solution:
def push_data(request):
q = m.B.objects
if request.is_ajax():
data = json.loads(request.body.decode('utf-8'))
if 'req_1' in data:
q = q.filter(bs__id__in=data['req_1'])
if 'req_2' in data:
q = q.filter(type__id__in=data['req_2'])
actual_data = q.values('name', 'id', 'type__name')
mtm_get(actual_data) ## down
return HttpResponse(json.dumps(list(actual_data)),
content_type='application/json; charset=utf8')
for many-to-many:
def mtm_get(data):
for d in data:
d['a_name'] = ', '.join(''.join(i) for i in m.B.objects.filter(
pk=d['id']).values_list('bs__name'))
I am getting this error during inserting data in many to many relationship in sqlalchemy.
Models.py
class Event(db.Model):
__tablename__ = 'event'
id = db.Column(db.String(255), primary_key=True)
title = db.Column(db.String(255))
image_url = db.Column(db.String(255))
category_id = db.Column(db.String(255), db.ForeignKey('category.id'),
nullable=True)
subheading = db.Column(db.String(255))
event_city = db.Column(db.String(255))
venue = db.Column(db.String(255))
start_date = db.Column(db.DateTime)
end_date = db.Column(db.DateTime)
description = db.Column(db.String(255))
speaker = db.relationship("Speaker",
secondary=association_table)
errors = {}
def __init(self, **kwargs):
print kwargs
speaker1 = db.session.query(Speaker).first()
print speaker
self.speaker.append(speaker1)
self.id = generate_id()
kwargs.pop(EVENT_FIELDS['EVENT_SPEAKER'])
kwargs.pop(EVENT_FIELDS['EVENT_CATEGORY'])
for key, value in kwargs.iteritems():
try:
setattr(self, key, value)
except ex:
Event.errors = FORM_EMPTY_FIELD.format(key)
association table is
association_table = db.Table('association',
db.Column('speaker_id', db.String(255),
db.ForeignKey('speaker.id')),
db.Column('event_id', db.String(255),
db.ForeignKey('event.id')))
when i am inserting data i am getting error as mention above
In a M2M relationship the association in the speaker column of your model Event must be passed as list (means between brackets []) in this way, please note in __init__ method the assignation of speaker :
def __init(self, **kwargs):
print kwargs
speaker1 = db.session.query(Speaker).first()
print speaker
self.speaker = [speaker1]
self.id = generate_id()
kwargs.pop(EVENT_FIELDS['EVENT_SPEAKER'])
kwargs.pop(EVENT_FIELDS['EVENT_CATEGORY'])
for key, value in kwargs.iteritems():
try:
setattr(self, key, value)
except ex:
Event.errors = FORM_EMPTY_FIELD.format(key)