Mysql index without key specification on replace? - mysql

I have the following code:
mytable.to_sql(name='mytable', con=engine, index=True, if_exists='replace')
But it keeps throwing the following error:
'(1170, "BLOB/TEXT column 'index' used in key specification without a key length")'[SQL: CREATE INDEX ix_mytable_index ON mytable (index)]
I think I understand why the error happens but in the context for the code above I don't know how to specify the length. I can't change the underlying database since this code was handed down to me.

Related

(1054, "Unknown column '' in 'field list'")

I know this question has been asked a couple of time but no previous answer was able to solve my problem.
I had a perfectly working model in Django that looked like this:
class Template(models.Model):
mat = models.CharField(max_length=50, null=True)
...
I had many instances of this model and up to now I was very happy with it. I recently decided that instead of a Charfield, this model was better suited to work with a ForeignKey in this position instead.
To get into details, the attribute ''mat'' was previously only referring to the name of another object instance. I decided to change it to the full fledged instance with a ForeignKey instead, like it should have always been. Therefore, the model was modified as follows:
class Template(models.Model):
mat = models.ForeignKey(Stock, on_delete=models.CASCADE, related_name='mat_stock', verbose_name="mat", null=True)
...
I followed this change with the regular */manage.py makemigrations, */manage.py migrate. While these two commands worked, I was unable to select any instance of Template in the shell without raising the following error:
OperationalError: (1054, "Unknown column 'myapp_template.mat_id' in 'field list'")
Similar situations I encountered were solved by manually adding a column in SQL with the following line:
ALTER TABLE database.myapp_template ADD mat INT;
Unfortunately this did not solve my problem.
I figured maybe the problem was that I already had instances of my object that had character values in the ''mat'' column. Django would expect integer values (specifically "id") after my migration, so I decided to create a completely new attribute for Template as follows:
class Template(models.Model):
pos_mat = models.ForeignKey(Stock, on_delete=models.CASCADE, related_name='mat_stock', verbose_name="mat", null=True)
...
This, I thought, would delete (or disregard) the "mat" column and create new "pos_mat" columns with the desired properties without having to handle old character values that wouldn't fit with the requirements. From there on it should be like adding a completely new ForeignKey attribute.
After the required and successful */manage.py makemigrations, */manage.py migrate I am still unable to access an instance of my model in the shell. I still get the same unpleasing:
OperationalError: (1054, "Unknown column 'myapp_template.mat_id' in 'field list'")
Would anybody know how to convince Django to go along with my changes? I am skeptical that rolling back migrations to zero will help me (it did not solve my problems in the past) and I hope it will not come to the deletion of my data. It is acceptable for my model to have an empty field in this column since I added a null=True to my attribute.
Thank you very much for your help. Have a good day.
I have solved my problem by rolling back to my last stable migration. From there I was able to migrate a model where 'mat' was absent and 'pos_mat' was the only attribute. This means my problem arose in the first migration from the old version of 'mat' to the new version of 'mat'. Basically keeping the same name but changing the attribute characteristics is a no go. I hope those with the same problem will be able to fix it with this.

Laravel : How can I change default indexing key length in morph table

I have table "invoice_relations" which is morph table.
So in migration I wrote :
$table->morphs('invoice_relations');
But it gives error while running migration as,
Syntax error or access violation: 1059 Identifier na
me 'invoice_relations_invoice_relations_id_invoice_relations_type_index' is too long in /var/www/html/st/sales-tantra/vendor/doctrine/dbal/
lib/Doctrine/DBAL/Driver/PDOStatement.php:105
Change your
$table->morphs('invoice_relations');
To this:
$table->morphs('invoice_relations', 'invoice_relations_morpf_key');
Or this:
$table->unsignedInteger("invoice_relations_id");
$table->string("invoice_relations_type");
$table->index(["invoice_relations_id", "invoice_relations_type"], "YOUR_INDEX_NAME");
But I think name for polymorphic relations name ends 'able', for example relationable.
https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations

Circular Dependency Error with SQLAlchemy using autoload for table creation

I am attempting to use the script found here.
I am connecting to an MS SQL database and attempting to copy it into a MySQL database. When the script gets to this line:
table.metadata.create_all(dengine)
I get the error of:
sqlalchemy.exc.CircularDependencyError
I reasearched this error and found that it occurs when using the autoload=True when creating a table. The solution though doesn't help me. The solution for this is to not use autoload=True and to make use of the use_alter=True flag when defining the foreign key, but I'm not defining the tables manually, so I can't set that flag.
Any help on how to correct this issue, or on a better way to accomplish what I am trying to do would be greatly appreciated. Thank you.
you can iterate through all constraints and set use_alter on them:
from sqlalchemy.schema import ForeignKeyConstraint
for table in metadata.tables.values():
for constraint in table.constraints:
if isinstance(constraint, ForeignKeyConstraint):
constraint.use_alter = True
Or similarly, iterate through them and specify them as AddConstraint operations, bound to after the whole metadata creates:
from sqlalchemy import event
from sqlalchemy.schema import AddConstraint
for table in metadata.tables.values():
for constraint in table.constraints:
event.listen(
metadata,
"after_create",
AddConstraint(constraint)
)
see Controlling DDL Sequences

Odd IntegrityError on MySQL: #1452

This is sort of an odd one but I'll try to explain as best I can. I have 2 models: one representing an email message (Message), the other a sales lead (AffiliateLead). When a form is submitted through the site, the system generates a lead and then emails. The Message model has an optional FK back to the Lead. From the Message models file:
lead = models.ForeignKey('tracking.AffiliateLead', blank=True, null=True)
Now, this basic shell works:
from tracking.models import Affiliate, AffiliateLead
from messages.models import Message
from django.contrib.auth.models import User
u = User.objects.get(username='testguy')
a = Affiliate.objects.get(affiliate_id = 'ACD023')
l = AffiliateLead(affiliate = a)
l.save()
m = Message(recipient=u, sender=u, subject='s', body='a', lead=l)
m.save()
However, the form view itself does not. It throws an IntegrityError when I try to save a Message that points to an AffiliateLead:
(1452, 'Cannot add or update a child row: a foreign key constraint fails (`app`.`messages_message`, CONSTRAINT `lead_id_refs_id_6bc546751c1f96` FOREIGN KEY (`lead_id`) REFERENCES `tracking_affiliatelead` (`id`))')
This is despite the fact that the view is simply taking the form, creating and saving the AffiliateLead, then creating and (trying) to save the Message. In fact, when this error is thrown, I can go into MySQL and see the newly-created lead. It even throws this error in the view when I re-retrieve the lead from the DB immediately before saving:
af_lead = AffiliateLead.objects.get(id = af_lead.id)
msg.lead = af_lead
msg.save()
Finally, if I immediately refresh (re-submitting the form), it works. No IntegrityError. If I have Django print out the SQL it's doing, I can indeed see that it is INSERTing the AffiliateLead before it tries to INSERT the Message, and the Message INSERT is using the correct AffiliateLead ID. I'm really stumped at this point. I've even tried manual transaction handling to no avail.
I'm not exactly sure why it happened, but I did seem to find a solution. I'm using South to manage the DB; it created Messages as InnoDB and AffiliateLead as MyISAM. Changing the AffiliateLead table to InnoDB ended the IntegrityErrors. Hope this helps someone else.

Errors creating generic relations using content types (object_pk)

I am working to use django's ContentType framework to create some generic relations for a my models; after looking at how the django developers do it at django.contrib.comments.models I thought I would imitate their approach/conventions:
from django.contrib.comments.models, line 21):
content_type = models.ForeignKey(ContentType,
verbose_name='content type',
related_name="content_type_set_for_%(class)s")
object_pk = models.TextField('object ID')
content_object = generic.GenericForeignKey(ct_field="content_type", fk_field="object_pk")
That's taken from their source and, of course, their source works for me (I have comments with object_pk's stored just fine (integers, actually); however, I get an error during syncdb on table creation that ends:
_mysql_exceptions.OperationalError: (1170, "BLOB/TEXT column 'object_pk' used in key specification without a key length")
Any ideas why they can do it and I can't ?
After looking around, I noticed that the docs actually state:
Give your model a field that can store a primary-key value from the models you'll be relating to. (For most models, this means an IntegerField or PositiveIntegerField.)
This field must be of the same type as the primary key of the models that will be involved in the generic relation. For example, if you use IntegerField, you won't be able to form a generic relation with a model that uses a CharField as a primary key.
But why can they do it and not me ?!
Thanks.
PS: I even tried creating an AbstractBaseModel with these three fields, making it abstract=True and using that (in case that had something to do with it) ... same error.
After I typed out that really long question I looked at the mysql and realized that the error was stemming from:
class Meta:
unique_together = (("content_type", "object_pk"),)
Apparently, I can't have it both ways. Which leaves me torn. I'll have to open a new question about whether it is better to leave my object_pk options open (suppose I use a textfield as a primary key?) or better to enforce the unique_togetherness...