Django - remove primary_key=True from an existing model? - mysql

I have a table that I've already migrated into the MySQL database and one of the fields has primary_key = True. I realized this needs to be different and I need to remove the primary_key = True. I'd like Django to create its own auto incrementing primary key fields (like it does with all models if you don't specify a primary_key).
If I simply remove the primary_key = True, Django complains because it can't auto-assign an auto-increment value to its new id field (which is now the primary key field).
What's the best way to change this one field to not have primary_key = True? This particular model doesn't have any records yet in the database, so I think I'm in a better position than if I had records in there. I'm not sure if I should just drop the table and migrate as if it's a brand new table or if I need to take some other approach?
Edit
What I actually tried:
python manage makemigrations accounting
The model in question is called Invoice and I'm wanting to change the field inv_num to not be the primary key
Django asks:
You are trying to add a non-nullable field 'id' to invoice without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option:
So I select option 1, and type 1.
Django creates the migration file, so I do:
python manage migrate accounting
And Django complains with:
django.db.utils.OperationalError: (1067, "Invalid default value for 'id'")
My research indicates that this is because you can't auto-assign a value to a primary key field.
Edit 2
The Model in question:
class Invoice(models.Model):
inv_num = models.CharField(max_length = 144, primary_key = True, verbose_name = 'Invoice Number')
brokerage = models.ForeignKey(Brokerage, blank = True, null = True, verbose_name = 'Brokerage')
lot = models.ForeignKey(Lot, on_delete = models.SET_NULL, blank = True, null = True, verbose_name = "Lot")
vendor = models.ForeignKey(Vendor, on_delete = models.SET_NULL, blank = True, null = True, verbose_name = 'Bill To (Vendor)')
contact = models.ForeignKey(Contact, on_delete = models.SET_NULL, blank = True, null = True, verbose_name = 'Bill To (Contact)')
due_date = models.DateField(blank = True, null = True, verbose_name = 'Date')
fund = models.ForeignKey(Fund, on_delete = models.SET_NULL, blank = True, null = True)
org_amt = models.DecimalField(max_digits = 12, decimal_places = 2, default = 0, verbose_name = 'Original Amount of Invoice')
amtos = models.DecimalField(max_digits = 12, decimal_places = 2, default = 0, verbose_name = 'Amount OS')
is_fine = models.BooleanField(default = False)
is_reversed = models.BooleanField(default = False, verbose_name = 'Has Been Reversed')
is_paid = models.BooleanField(default = False, verbose_name = 'Is Paid')
is_locked = models.BooleanField(default = False, verbose_name = 'Is Locked')
is_archived = models.BooleanField(default = False, verbose_name = 'Is Archvied')
org_je = models.CharField(max_length = 144, blank = True, null =True, verbose_name = 'Original JE')
There are a number of other models in this Django App that have Invoice as a foreign key. But those too don't have any data in them in the database.
I wonder if I should just drop the whole app from the database, and re-migrate it in? I do have a bunch of other apps that have data I cannot simply drop though.

Related

SqlAlchemy Multi language support

I have next model for SqlAlchemy:
class Post(db.Model):
__tablename__ = 'posts'
post_id = db.Column(db.Integer, primary_key=True)
created_at = db.Column(db.DateTime)
# I dont want list of all title translations: titles = db.relationship("Content").
# How can I pass lang_code here for properly title value?
title = db.relationship("Content",
primaryjoin="and_(Content.post_id==Post.post_id,
Content.lang_code=='%s')" % lang_code, uselist=False)
class Content(db.Model):
__tablename__ = 'content'
content_id = db.Column(db.Integer, primary_key=True)
value = db.Column(db.String())
lang_code = db.Column(db.String(2)) # for ex: 'en', 'fr', 'de', 'ru'
post_id = db.Column(db.Integer, db.ForeignKey('posts.post_id'))
I want to get Post contains 'en' title without list of all translations in my code. I want to pass lang_code value into it but I don't know how.
And access it with something like this:
result = Post.query.filter_by(author_id=1).pass_custom_var_to_all_posts_in_query(lang_code='en').paginate(page, 20, False)
Or, may be, there are exists way to filter child rows (and show one title with current language instead of list of all titles)
I would use Association Proxy with attribute_mapped_collection.
Your model somewhat reworked:
class Post(Base):
__tablename__ = 'posts'
post_id = Column(Integer, primary_key=True)
name = Column(String)
created_at = Column(DateTime)
_titles = relationship(
"Content",
collection_class=attribute_mapped_collection("lang_code"),
)
titles = association_proxy(
'_titles', 'lang_code',
creator=lambda k, v: Content(lang_code=k, value=v),
)
class Content(Base):
__tablename__ = 'content'
content_id = Column(Integer, primary_key=True)
value = Column(String())
lang_code = Column(String(2)) # for ex: 'en', 'fr', 'de', 'ru'
post_id = Column(Integer, ForeignKey('posts.post_id'))
Then you can create Post instances:
p = Post(
name="no english",
titles={
'de': 'liebe',
'es': 'amor',
},
)
session.add(p)
Adding/Updating is a simple as p.titles['it'] = 'amore', and deleting as del p.titles['it'].
Finally, your query with filter for Title which have translation to the specific language:
q = (
session.query(Post)
# .filter(Post.author_id == 1)
.filter(Post.titles.contains('en'))
)
you can use this https://sqlalchemy-i18n.readthedocs.io/en/latest/
this library will give the ability to create table for translation for each model and get the localized data

How get value from mule payload

How I get value from mule payload. I am unable to get from mule payload.
ExceptionMessage{payload=ActiveMQTextMessage {commandId = 14, responseRequired = false, messageId = ID:localhost.localdomain-59898-1431596266048-1:1:5:1:1, originalDestination = null, originalTransactionId = null, producerId = ID:localhost.localdomain-59898-1431596266048-1:1:5:1, destination = queue://delivery-queue-A, transactionId = TX:ID:localhost.localdomain-59898-1431596266048-1:1:1, expiration = 0, timestamp = 1431596274660, arrival = 0, brokerInTime = 1431596274672, brokerOutTime = 1431596274700, correlationId = null, replyTo = null, persistent = true, type = null, priority = 4, groupID = null, groupSequence = 0, targetConsumerId = null, compressed = false, userID = null, content = org.apache.activemq.util.ByteSequence#3128d4c1, marshalledProperties = org.apache.activemq.util.ByteSequence#6fa7e41d, dataStructure = null, redeliveryCounter = 3, size = 0, properties = {MULE_SESSION=, MULE_ROOT_MESSAGE_ID=e33be8a0-fa1c-11e4-9365-000c294271b7, MULE_ENDPOINT=jms://delivery-queue-A, Content_Type=text/plain;charset=UTF-8, MULE_ENCODING=UTF-8}, readOnlyProperties = true, readOnlyBody = true, droppable = false, jmsXGroupFirstForConsumer = false, text = CCD150507074415642 (copy).xml====
}
You can retrieve the original payload from an org.mule.message.ExceptionMessage payload with:
#[message.payload.payload]
Please check if the message you're printing is actually a complex object or a string representation of the message, that would define the strategy for accessing the values.
For this you can log with the following expression #[payload.getClass().getName()]
First you know your payload type whether it is String or Object then try to make use of the methods on payload.
You can extract payload using #[message.payload] and value from #[message.payload.'key']

Model in django to store working hours of an employee for specific year, month and week

I am creating a Django application for online attendance system that has to store weekly working hours of employees for few years(5 or 6)
I want to create a table, that has employeeid, year, month, week and hours(example 4hrs for week1 in Jan 2015 for employee with id 200)
I tried creating models(year, month, week, record) with few ManyToManyFields and Foreignkey Fields, but ended up in creating tables that link years and employeeid, employeeid and month, years and month but not a table with the fields employeeid, week, month and year.
Could anyone tell me the relations between the fields to be used in models to create a database for this.
Thanx in advance
Here is my Models.py -
from django.db import models
class Month(models.Model):
id = models.IntegerField(primary_key = True, null = False)
weeks = models.ManyToManyField(Week, null = True)
class Year(models.Model):
id = models.IntegerField(primary_key = True, null = False)
month = models.ManyToManyField(Month, null = True)
class UserId(models.Model):
id = models.IntegerField(primary_key = True, null = False)
name = models.CharField(max_length = 56) // employee name
year = models.ForeignKey(Year, null = True)
class Week(models.Model):
id = models.IntegerField(primary_key =True, null = False)
working_hours = models.IntegerField(null = True, default = 0)
class Record(models.Model):
id = models.IntegerField(primary_key = True, null = False)
month = models.ManyToManyField(Month, null = True)
year = models.ManyToManyField(Year, null = True)
week = models.ManyToManyField(Week, null=True)
userid = models.ForeignKey(UserId, null = True)
This model will satisfy your requirements
Note: you don't have to create primary key(id) field, it will be automatically created by django.
from django.db import models
class Employee(models.Model):
name = models.CharField(max_length = 56)
class Record(models.Model):
employee = models.ForeignKey(Employee)
month = models.IntegerField()
year = models.IntegerField()
week = models.IntegerField()
hours = models.IntegerField()
class Meta:
unique_together = (('employee', 'month', 'year', 'week'),)

Why 2 queries are executed instead of one?

I have following piece of code:
def detail(request, popular_id):
try:
popular = Popular.objects.get(pk = popular_id)
share = Share.objects.get(isin = popular.isin) #LINE 1
chart_data_json = share.get_chart_data_json()
except Popular.DoesNotExist:
raise Http404
return render(request, 'popular/detail.html', {'popular': popular, 'chart_data': chart_data_json})
In LINE 1 I noticed using debug-toolbar that there are two queries get executed:
SELECT `share_share`.`id`, `share_share`.`symbol`, `share_share`.`isin`, `share_share`.`name`, `share_share`.`market`, `share_share`.`updated` FROM `share_share` WHERE `share_share`.`id` = 1
and
SELECT `share_share`.`id`, `share_share`.`symbol`, `share_share`.`isin`, `share_share`.`name`, `share_share`.`market`, `share_share`.`updated` FROM `share_share` WHERE `share_share`.`isin` = 'US5949181045'
I cannot understand why we need the first query and how to avoid it?
EDIT:
Model definition of share:
class Share(models.Model):
symbol = models.CharField(max_length = 32)
isin = models.CharField(max_length = 12)
name = models.CharField(max_length = 256)
market = models.CharField(max_length = 64)
updated = models.BooleanField(default = False)
def get_chart_data_json(self):
quote_model = create_quote_model(str(self.isin))
data = quote_model.objects.values('date', 'adj_close', 'volume')
chart_data = []
for d in data.iterator():
chart_data.append({'date': d['date'].isoformat(), 'value': d['adj_close'], 'volume': d['volume']})
chart_data_json = json.dumps(chart_data)
return chart_data_json
def __unicode__(self):
return self.isin
Model definition of popular:
class Popular(models.Model):
title = models.CharField(max_length = 120)
text = models.CharField(max_length = 1024)
isin = models.ForeignKey(Share)
def __unicode__(self):
return self.title
First query is evaluated when you access foreign key isin from popular object:
share = Share.objects.get(isin = popular.isin)
Second query gets Share object:
share = Share.objects.get(isin = popular.isin)
If you want just one query at #LINE 1 you should replace it with:
share = popular.isin #LINE 1

Django and MySQL -- the data is different between the two

I have a Django app that uses MySQL as a backend. I'm having difficulties where the raw MySQL records show one value, but Django presents something else in the web app.
For example, I have a table for client data. One of the fields in each record is called snailMailInvoice and is a Y/N choice -- default is Y (varchar type).
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| snailMailInvoice | varchar(3) | NO | | Y | |
The raw MySQL:
select * from systems_system_contact where lastName="SomeClient";
...a bunch of other fields... | snailMailInvoice |
...a bunch of other fields... | N
Then, in the Django App, the form displays Y (the other choice). It is like the Django App can't see the MySQL value, so it defaults to Y. If, through the Django App, I select N and save the form, THEN the value sticks to N in Django.
Why would this be happening?
EDIT - to add some code
Forms.py:
class System_Contact_Form(ModelForm):
class Meta:
model = System_Contact
exclude = ('isMainContact', 'systemOwner', 'companyName', 'isRessyContact')
Views.py:
def contact_details(request, scID):
redirect_to = request.REQUEST.get('next', '/systems/contacts/')
if request.method == 'POST':
syscontEdit = System_Contact.objects.get(pk=scID)
form = System_Contact_Form(request.POST, instance=syscontEdit)
if form.is_valid():
form.save()
return HttpResponseRedirect(redirect_to)
else:
syscontView = System_Contact.objects.get(pk=scID)
form = System_Contact_Form(instance=syscontView)
c = {
'form':form,
'cancel':redirect_to
}
return render_to_response('pages/systems/contact_details.html', c, context_instance=RequestContext(request))
Models.py:
class System_Contact(models.Model):
IS_MAIN_CONTACT_CHOICES = (
('Y', 'Yes'),
('N', 'No'),
)
IS_SYSTEM_OWNER_CHOICES = (
('Y', 'Yes'),
('N', 'No'),
)
IS_RESSY_CONTACT_CHOICES = (
('Y', 'Yes'),
('N', 'No, this is a commercial contact'),
)
TRADE_CHOICES = (
('EL', 'Electrician'),
('LA', 'Landscaper'),
('PL', 'Plumber'),
('TR', 'Trencher'),
)
SNAIL_MAIL_CHOICES = (
('Y', 'Yes'),
('N', 'No'),
)
SNAIL_MAIL_INVOICE_CHOICES = (
('Y', 'Yes'),
('N', 'No'),
)
firstInitial = models.CharField(max_length = 10, verbose_name = 'First Initial', blank = True, null = True)
firstName = models.CharField(max_length = 60, verbose_name = 'First Name', blank = True, null = True)
lastName = models.CharField(max_length = 160, verbose_name = 'Last Name', blank = True, null = True)
phonetically = models.CharField(max_length = 100, verbose_name = 'Phonetically', blank = True, null = True)
companyName = models.CharField (max_length = 160, verbose_name = 'Company Name', blank = True, null = True) #Only used for Commercial Owners, no other field needed
homePhone = models.CharField(max_length = 60, verbose_name = 'Home Phone Number', blank = True, null = True)
officePhone = models.CharField(max_length = 60, verbose_name = 'Office Phone Number', blank = True, null = True)
cellPhone = models.CharField(max_length = 60, verbose_name = 'Cell Phone Number', blank = True, null = True)
faxNumber = models.CharField (max_length= 60, blank=True, null=True, verbose_name = 'Fax Number')
isMainContact = models.CharField (max_length = 3, verbose_name = 'Is the Main Contact?', choices = IS_MAIN_CONTACT_CHOICES, default='N')
isRessyContact = models.CharField (max_length = 3, verbose_name = 'Is this a Ressy Contact?', choices = IS_RESSY_CONTACT_CHOICES, default='Y')
isArchived = models.BooleanField(verbose_name = 'Archived?', default = False)
systemOwner = models.CharField (max_length = 3, verbose_name = 'Is a System Owner?', choices = IS_SYSTEM_OWNER_CHOICES, default='N') #this is just a flag to say they own a system
worksFor = models.CharField (max_length = 70, verbose_name = 'Works For', blank = True, null = True)
tradeType = models.ForeignKey(Contact_Trade, blank=True, null=True, verbose_name='Trade')
emailAddress = models.EmailField(verbose_name = 'Email Address', blank = True, null = True)
billingAddress = models.CharField(max_length = 150, verbose_name = 'Billing Address', blank=True, null=True )
billingCity = models.CharField(max_length = 90, verbose_name = 'Billing City', blank=True, null=True)
billingProvince = models.CharField(max_length = 30, verbose_name = 'Billing Province', blank=True, null=True)
billingPostalCode = models.CharField(max_length = 10, verbose_name = 'Billing Postal Code', blank=True, null=True)
snailMailOnly = models.CharField(max_length = 3, verbose_name = 'Snail Mail Only?', choices = SNAIL_MAIL_CHOICES, default='Y')
snailMailInvoice = models.CharField(max_length = 3, verbose_name = 'Snail Mail Invoice?', choices = SNAIL_MAIL_INVOICE_CHOICES, default='Y')
OK -- I figured it out.
I realised there was something connected with the fact that in my CSV file, the snailMailInvoice field is the LAST field on each line. Thus, at the end of the line there is a carriage return. I assumed that this was a \n -- thus in my MySQL command to import the CSV, I state terminated by '\n'.
However, the MySQL picked up a '\r' on EVERY line and was adding it to the snailMailInvoice field. Thus, every record has either a Y or a N with a \r attached.
I amended my MySQL import statement to have: lines terminated with '\r\n' Now everything is working as expected.
Lesson learned.
Thanks for the help.