I'm creating a web app with Clojure and Luminus, but when I create a migration file with all the tables I need, it will only create the first. This is my user-table.up.sql file:
CREATE TABLE UserTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
first_name VARCHAR(50),
last_name VARCHAR(50),
gender VARCHAR(50),
email VARCHAR(50) UNIQUE,
password VARCHAR(400),
time_stamp TIMESTAMP,
is_active BOOLEAN
);
CREATE TABLE LoginTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
time_stamp TIMESTAMP
);
When I run lein run migrate, only the table UserTable is created. Is this supposed to work like this? Do I need to create a migration file for each table?
As you are using Luminus, you are probably using Migratus. If you want to execute multiple statements in one sql file, read this:
https://github.com/yogthos/migratus#multiple-statements
Just to let Michiel answer here according your case, to run multiple statements in your migration, separate them with --;; in your case:
CREATE TABLE UserTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
first_name VARCHAR(50),
last_name VARCHAR(50),
gender VARCHAR(50),
email VARCHAR(50) UNIQUE,
password VARCHAR(400),
time_stamp TIMESTAMP,
is_active BOOLEAN
);
--;;
CREATE TABLE LoginTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
time_stamp TIMESTAMP
);
Related
TL\DR version - Find and delete rows in Postgres with same date but different time, leaving one record per date.
Long read:
At some point we've migrated our app's backend to a newer version - this is a Django application - migrated from Python 2, Django 1.8 to Python 3 - Django 4, and with this update we're changed timezone for backend from UTC+2 to UTC+3. And now strange things happens - records which previously successfully have been read from db with queryset StatChildVisit.objects.filter(date=day, garden_group=garden_group) - (day is a python's date only not datetime) after update returns empty queryset, although records for that day are still in db. More so newly created records have different time in them - records created with old timezone looks like 2022-12-28 22:00:00.000000 +00:00 new records looks like 2022-12-28 21:00:00.000000 +00:00
Seems that bug happened because date field in django's model have been declared as DateTimeField -
class StatChildVisit(models.Model):
child = models.ForeignKey(Child, on_delete=models.CASCADE)
date = models.DateTimeField(default=timezone.now)
visit = models.BooleanField(_('Atended'), default=True)
disease = models.BooleanField(_('Sick'), default=False)
other_approved = models.BooleanField(_('Other approved'), default=False)
garden_group = models.ForeignKey(GardenGroup, verbose_name=_('Garden group'), editable=False, blank=True, null=True, on_delete=models.CASCADE)
rossecure_visit = models.ForeignKey('rossecure.Visits', editable=False, null=True, blank=True, on_delete=models.CASCADE)
class Meta:
verbose_name = _('Attendence')
verbose_name_plural = _('Attendence')
index_together = (
('date', 'garden_group'),
)
unique_together = (
('date', 'child'),
)
all records are always being created with date only (not datetime) passing to constructor
So we've decided to migrate this field to DateField, but after migration field type in DB is still 'timestamp with time zone', and besides, because this is a production database users after finding that some data looks like lost partially recreated records.
So now we have multiple records for same day but with different time which need to be deleted and because of constrains table column can not be altered with ALTER TABLE reports_statchildvisit ALTER COLUMN date TYPE date;
Because table have rather large records count (about 4 million) I think that problem should be solved via SQL side, and not Django side. My plan is to delete duplicates and then change column type to date.
I've tried to alter records with
update reports_statchildvisit
set date = date(date) + '21:00:00'::time
but because I've tried that after users created similar records script failed with ERROR: duplicate key value violates unique constraint
UPD: DDL on the SQL side looks like this:
create table public.reports_statchildvisit
(
id serial
primary key,
date timestamp with time zone not null,
visit boolean not null,
disease boolean not null,
child_id integer not null
constraint reports_statchil_child_id_30fbdf92a34d3fea_fk_children_child_id
references public.children_child
deferrable initially deferred,
garden_group_id integer
constraint repor_garden_group_id_ef61dd52421b5d2_fk_project_gardengroup_id
references public.project_gardengroup
deferrable initially deferred,
other_approved boolean not null,
rossecure_visit_id integer
constraint repo_rossecure_visit_id_488614f59207663f_fk_rossecure_visits_id
references public.rossecure_visits
deferrable initially deferred,
constraint reports_statchildvisit_date_3d6916481fe1e727_uniq
unique (date, child_id)
);
alter table public.reports_statchildvisit
owner to django;
create index reports_statchildvisit_10e12719
on public.reports_statchildvisit (garden_group_id);
create index reports_statchildvisit_42d2af72
on public.reports_statchildvisit (rossecure_visit_id);
create index reports_statchildvisit_date_66064e65c46d4137_idx
on public.reports_statchildvisit (date, garden_group_id);
create index reports_statchildvisit_f36263a3
on public.reports_statchildvisit (child_id);
Is it possible to make a foreign key value from specific values in the field from the table?
For EXA: To create a new record, HR and POC have foreign key via the employee table, but HR can bring only "HR" (hr1, hr2) values from "name" field - group by group_name field. Also POC table: all values grouped by "POC" (poc1 and poc2)
TNX alot
I found a solution.
In Django model should add "limit_choices_to" into the field.
limit_choices_to={"group_code": "2"}
group_code: group by this field from Group model, "2" the value for lookup
employee_type = models.ForeignKey(
Group,
related_name="employee_type",
verbose_name="Employee Type",
on_delete=models.CASCADE,
limit_choices_to={"group_code": "2"},
blank=False,
default="None",
)
My models:
class TestSkill(models.Model):
name = models.CharField(max_length=255)
value = models.CharField(max_length=255)
class Girl(models.Model):
skills = models.ManyToManyField(TestSkill)
this has created following sql statement:
CREATE TABLE "my_app_girl_skills" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "girl_id" integer NOT NULL REFERENCES "my_app_girl" ("id"), "testskill_id" integer NOT NULL REFERENCES "my_app_testskill" ("id"))
And after I tried manually to create a row in db using sql lite browser I 've got an error:
Foreign constraint failed
I have two models:
class StateTax(models.Model):
name = models.CharField(max_length=256)
abbr = models.CharField(max_length=64, primary_key=True)
rate = models.IntegerField(default=0)
class Account(models.Model):
name = models.CharField(max_length=32)
tax_regions = models.ManyToManyField(SalesTaxRegion, blank=True, null=True, related_name="accounts")
However the SQL Django creates during syncdb seems to ignore the primary_key option. For example:
CREATE TABLE `airship_salestaxregion` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`name` varchar(256) NOT NULL,
`abbr` varchar(64) NOT NULL,
`rate` integer NOT NULL
)
;
CREATE TABLE `airship_account_tax_regions` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`account_id` integer NOT NULL,
`salestaxregion_id` integer NOT NULL,
UNIQUE (`account_id`, `salestaxregion_id`)
)
;
(note there is still an ID column in the first table and the relationship table references it)
As Like It says in the comment, you're getting your tables mixed up, you've given us python code for StateTax, not SalesTaxRegion.
I've tested your StateTax code with Django 1.4 and Postgres 9.2 and I get the following -
-- DROP TABLE testing_statetax;
CREATE TABLE testing_statetax
(
name character varying(256) NOT NULL,
abbr character varying(64) NOT NULL,
rate integer NOT NULL,
CONSTRAINT testing_statetax_pkey PRIMARY KEY (abbr)
)
There's no additional id field added.
I've got a tiny little problem that, unfortunately, is taking all my time.
It is really simple, I already have my database and I created then modified models.py, and admin.py. Some staff users, who will need to enter values in my database, need the simpliest form to do so.
Here is my database :
-- Table NGSdb.line
CREATE TABLE IF NOT EXISTS `NGSdb`.`line` (
`id` INT NOT NULL AUTO_INCREMENT ,
`value` INT NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB;
CREATE UNIQUE INDEX `value_UNIQUE` ON `NGSdb`.`line` (`value` ASC) ;
-- Table NGSdb.run_has_sample_lines
CREATE TABLE IF NOT EXISTS `NGSdb`.`run_has_sample_lines` (
`line_id` INT NOT NULL ,
`runhassample_id` INT NOT NULL ,
PRIMARY KEY (`line_id`, `runhassample_id`) ,
CONSTRAINT `fk_sample_has_line_line1`
FOREIGN KEY (`line_id` )
REFERENCES `NGSdb`.`line` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_sample_has_line_run_has_sample1`
FOREIGN KEY (`runhassample_id` )
REFERENCES `NGSdb`.`run_has_sample` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
-- Table NGSdb.run_has_sample
CREATE TABLE IF NOT EXISTS `NGSdb`.`run_has_sample` (
`id` INT NOT NULL AUTO_INCREMENT ,
`run_id` INT NOT NULL ,
`sample_id` INT NOT NULL ,
`dna_quantification_ng_per_ul` FLOAT NULL ,
PRIMARY KEY (`id`, `run_id`, `sample_id`) ,
CONSTRAINT `fk_run_has_sample_run1`
FOREIGN KEY (`run_id` )
REFERENCES `NGSdb`.`run` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_run_has_sample_sample1`
FOREIGN KEY (`sample_id` )
REFERENCES `NGSdb`.`sample` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
Here is my models.py :
class Run(models.Model):
id = models.AutoField(primary_key=True)
start_date = models.DateField(null=True, blank=True, verbose_name='start date')
end_date = models.DateField(null=True, blank=True, verbose_name='end date')
project = models.ForeignKey(Project)
sequencing_type = models.ForeignKey(SequencingType)
def __unicode__(self):
return u"run started %s from the project %s" % (self.start_date,self.project)
class Line(models.Model):
id = models.AutoField(primary_key=True)
value = models.IntegerField()
def __unicode__(self):
return u"%s" % str(self.value)
class RunHasSample(models.Model):
id = models.AutoField(primary_key=True)
run = models.ForeignKey(Run)
sample = models.ForeignKey(Sample)
dna_quantification_ng_per_ul = models.FloatField(null=True, blank=True)
lines = models.ManyToManyField(Line)
def __unicode__(self):
return u"Sample %s from run %s" % (self.sample, self.run)
And here is my admin.py :
class RunHasSamplesInLine(admin.TabularInline):
model = RunHasSample
fields = ['sample', 'dna_quantification_ng_per_ul', 'lines']
extra = 6
class RunAdmin(admin.ModelAdmin):
fields = ['project', 'start_date', 'end_date', 'sequencing_type']
inlines = [RunHasSamplesInLine]
list_display = ('project', 'start_date', 'end_date', 'sequencing_type')
As you can see, my samples are displayed in lines in the run form so that the staff can easily fullfill the database.
When I try to fill the database I have this error :
(1054, "Unknown column 'run_has_sample_lines.id' in 'field list'")
Of course, there are no field "lines" in my database ! It is a many to many field so I already created my intermediate table !
Okay okay ! So I tried to create the model for the intermediate table (run_has_sample_lines) and add a "through" to the ManyToManyField in the RunHasSample model. But, as I add manually the "through", I cannot use the ManyToMany field. The only way to add lines to the admin view is to stack them in lines... As you can see the samples are already in lines, it is impossible to put a new "inlines" in the already in lines samples...
Finally, I just tried to see what django had created with the manage.py sqlall.
I see that :
CREATE TABLE `run_has_sample_lines` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`runhassample_id` integer NOT NULL,
`line_id` integer NOT NULL,
UNIQUE (`runhassample_id`, `line_id`)
)
;
ALTER TABLE `run_has_sample_lines` ADD CONSTRAINT `line_id_refs_id_4f0766aa` FOREIGN KEY (`line_id`) REFERENCES `line` (`id`);
It seems that there are no foreign key on the run_has_sample table whereas I created it in the database in the first place. I guess that the problem is coming from here but I cannot resolve it and I really hope that you can...
Thank you very much !
you may wish to try a 'through' attribute on the many-to-many relationship and declare your intermediate table in Django.
I found where the problem is...
It is not a problem in the ManyToManyField but in the intermediate table. Django refused that my intermediate table doesn't have an unique id !
So, in the sql which created django, it created automatically an unique id named "id", but in my database I didn't create one (because the couple of two foreign key is usually enough).
Next time, I'll be more carefull.