AdonisJs: create migration for existent database schema - adonis.js

I have an existent Postgresql database schema which I wrote in SQL. It initializes extensions, enum types, and defines many tables with foreign keys, constraints, indexes, etc.
Now I wish to build an AdonisJs app around that database. I would like new developers to be able to set up an empty database with the same schema, without having to run the SQL command in psql themselves.
I do not want to write all the schema using the Adonis schema builder DSL because there are many tables and it would take a lot of time to translate.
In ruby on Rails, the schema would be kept updated in the db/schema.rb file and new developers would spin up their dev environment using rails db:schema:load. What is the equivalent in AdonisJS?
The current way I'm doing it is by creating a migration that basically runs the raw SQL query. But I'm convinced there should be a cleaner way. Or even a way to get this SQL file away from my migration.
import Database from '#ioc:Adonis/Lucid/Database'
import BaseSchema from '#ioc:Adonis/Lucid/Schema'
export default class extends BaseSchema {
public async up () {
const schemaSql = this.initialSchema()
console.log(schemaSql)
await Database.rawQuery(schemaSql)
}
public async down () {
}
public initialSchema() {
const fs = require('fs');
const path = require('path');
var data = fs.readFileSync(path.resolve(__dirname, './../initial_schema.sql'));
return data.toString();
}
}
and then inside database/initial_schema.sql I have:
CREATE EXTENSION IF NOT EXISTS citext;
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION IF NOT EXISTS btree_gist;
DROP TYPE IF EXISTS nivel_formacion;
CREATE TYPE nivel_formacion AS ENUM ('secundaria', 'grado', 'maestria', 'doctorado');
CREATE TABLE "foobar" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid(),
"name" varchar NOT NULL,
"created_at" timestamp NOT NULL,
"updated_at" timestamp NOT NULL
);
-- ...etc etc etc..

Related

Does Django use case sensitive filenames for FileField with MySQL backend?

I'm using Django 3.1.3 and have a model with a FileField field. When I upload a file with same name, but different case, the logic I have is reporting that it is a duplicate. For example:
Files <QuerySet ['92/565/20191222_152213.jpg', '92/565/cs_731__DSC8110.jpg', '92/565/ADs-2.MP4']>, this 92/565/ADS-2.mp4
The logic is...
other_pieces_in_room = Piece.objects.filter(room__id=self.room_id)
other_files_in_room = other_pieces_in_room.values_list('file', flat=True)
mylog.debug("Files {}, this {}".format(other_files_in_room, file.name))
if file.name in other_files_in_room:
raise forms.ValidationError("...")
Model (relevant fields) is:
class Piece(models.Model):
file = models.FileField(upload_to=media_location)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
Any thoughts as to what is going on?
For my case, the database was created with the default settings. The FileField in Django is stored in the database as a varchar and when doing:
show full columns from gallery_piece;
I could see that the field is using collation utf8_general_ci (which is case-insensitive).
I altered the database and all the char/varchar table fields to use utf8mb4 character set and utf8mb4_bin collation, using commands like:
ALTER TABLE gallery_exhibit MODIFY file varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
Once done, the filename (and other char type fields) are treating files as case sensitive. I did read that on file upload, the validation will be case-sensitive, so will pass, but then a database integrity error will be encountered, when saving an entry with only case differences using the default collation.
For production, when I create the database, I'll need to do:
CREATE DATABASE mydb
CHARACTER SET utf8mb4
COLLATE utf8mb4_bin;

Separate Spock.DbUnit content for each case in one Specification

I am using be.janbols.spock.extension.dbunit
But content is called for all cases.
How specify it for each case?
#DbUnit def content = {
CATEGORY(CATEGORY_ID: 1L, CATEGORY_NAME: "N", CATEGORY_IMAGE:"I")
}
https://github.com/janbols/spock-dbunit
Yes you would require it at global level of the testcase for class which you are testing.
It would generally be required while testing service layer classes which have many DAOs injected in them.
After initial content setup i.e the values you want to be seen in your inmemory database like H2
Then in, the setup , specify the table schema like,
def setup() {
new Sql(dataSource).execute("CREATE TABLE Category(category_id INT PRIMARY KEY, category_name VARCHAR(255), category_image VARCHAR(255))")}
Do not forget to cleanup after each testcase

Django: How to insert sql statements into sqlite3 database and configure with models

I'm using Django for a project. I have a .sql file containing insert statements. How can I get them into my sqlite3 database and have them work with my models?
The project "fortune" has a models.py file that looks like the following:
class fortune(models.Model):
id = models.IntegerField(primary_key=True)
category = models.CharField(max_length=50)
length = models.IntegerField()
aphorism = models.CharField(max_length=5000)
I have a .sql file with a list of Insert statements like the follwing:
INSERT INTO "fortune_fortune" VALUES(1,'fortunes',127,'Arbitrary Text');
When I run .schema on my db.sqlite3 file which is configured with my project I see:
CREATE TABLE fortune_fortune(id integer, category varchar(50), length integer, aphorism varchar(5000));
I've tried using .read in my sqlite shell with no luck. I've tried typing "sqlite3 file.sqlite3 < file.sql" in bash as well. There is something I'm missing here, but I can't seem to ID the problem.
Thanks for your help.
ok, wait.. normally you dont use sql statements to insert data into db, if you work with django.
to insert data into db, you work with django ORM which is way much fun than these ugly sql statements.
fortune = fortune(category='new cat', length=19, aphorism='i love life')
fortune.save()
then as a result, you will have one new row in fortune table in your db. just read django docs and you feel happy!
and one more thing, class names are always in capital.
to your issue:
Django provides a hook for passing the database arbitrary SQL that’s executed just after the CREATE TABLE statements when you run migrate. You can use this hook to populate default records, or you could also create SQL functions, views, triggers, etc.
The hook is simple: Django just looks for a file called sql/<modelname>.sql, in your app directory, where <modelname> is the model’s name in lowercase.
more in docs

Creating vs Modifying in backbone.js

This is my first application using backbone and REST API, I'm a bit confused with some specific scenarios when it comes to creating-editing. So if the model exits on server, it will EDIT, if it doesn't it CREATES.
When I pass on a unique identifier in my model, it knows it exits, but if I pass a combination of existing data without a unique identifier it always assumes it should CREATE. I'm not sure if this should be solved on client side or server.
For instance:
var exportationMod = new Backbone.Model({ 'asset': '/api/v1/asset/'+this.assetID+'/', 'export_configuration': '/api/v1/exportconfiguration/'+this.model.get('id')+'/' });
exportationMod.url = '/api/v1/exportation/';
exportationMod.save();
OK so the server is running with django + tastypie. Should this be validated by the client by first making an extra query, on the server (maybe there is a way of setting a combination of unique keys like mysql), or is there another setting I can tweak so it edits instead of creating?
If you pass data to the server without some unique id, how would the server know what to update?
If it makes sense for your situation, you can override isNew() in your model.
var MyModel = Backbone.Model.extend({
idAttribute: 'somethingUnique',
url: '/api/v1/exportation/',
isNew: function(){
// return true if you want create (POST),
// return false if you want update (PUT)
}
});
By default it looks like this (with the above model, this.id would be the idAttribute value above):
// A model is new if it has never been saved to the server, and lacks an id.
isNew: function() {
return this.id == null;
},
If you want to edit something that already exists on the server, you should just fetch it first before editing/saving it. Also, if there is some unique id that is not called 'id' you can override that on the model as well (see above).

Mapping a sql view to a php entity with doctrine2

I have a view in my database created with
CREATE VIEW TBL_TITLE (...)
That view is described in yaml by
HQ\Title:
type: entity
table: TBL_TITLE
fields:
(...)
lifecycleCallbacks: { }
This works fine: my entities are loaded and written correctly. But when I run orm:schema-tool:update, I get
CREATE TABLE TBL_TITLE (...);
So doctrine2 (2.1.6) doesn't see that TBL_TITLE already exists as a view and wants to create a table. How can I declare TBL_TITLE as a view so that schema-tool recognize it?
You cannot, the schema tool isn't able to handle that at current state.