Laravel Dynamic Database Table Names - database

Is there a way to create database tables dynamically in Laravel. I have one Laravel build which has a database schema for quotes using the migrations tool. There will be several customers using the system which need to each have their own database table.
What I would like to happen is that when a function is called by the customer it will use the quotes schema to create a new table like 'customer1_quotes' and use this table for the customer in future. Additionally when migrations are run it will apply the updates to all tables with the given name structure (*_quotes).
If anyone has details to achieve this or a recommend alternative approach please message :)

Create a trait used by observers
Create a trait which loops through your customers and creates/updates the tables. You don't have to be in a migration to call DB::.
Use the trait in create/update controllers or better for model create/update observers. You could also create a console command for manual triggering or testing.
This should not be executed during maintenance. Using php artisan down should ensure no jobs are run during migrations.
The migrations for the customer{id}_quotes tables can loop through the available tables by querying table names using LIKE and/or REGEXP. See link below.
Links
Laravel Model Observers
How to dynamically set table name in Eloquent Model
Laravel's table Blueprint docs (5.8)
Get table names using LIKE or REGEXP
Optimization: Chunking results when getting query builder results
Edit: A repeatable migration probably won't work well and is confusing to others. Using a trait for flexibility to use for an observer is better for this.

Related

Is there any way to create migrations in beego?

I haven't found in documentation anything except "syncdb" command which create database tables from scratch. Is there any command to create and run migrations based on ORM model? Like in django? Add field, change type, etc.
No, orm.RunSyncdb(name, force, verbose) and it's command line equivalent only do a small subset of what tools like django's south can do.
Beego's orm can:
Create new tables from scratch
Drop all tables (force = true)
Add new columns as you extend your model
You need to handle dropping columns and any changes to the column parameters used to initially create the table.
Sadly beego doesn't include this feature, but no framework in go (as of today) does.
Instead they all relay that to other libraries to handle.
What you can do however is use goose for migrations:
https://bitbucket.org/liamstask/goose
or any other migration library as discussed in the following thread:
http://www.reddit.com/r/golang/comments/2dlbz5/database_migration_handling_in_go/
Remember that due to the modularity of beego you can also use any another orm (like gorm).
Feel free to look for : avelino/awesome-go in google if you want a list of tools/libs around the go ecosystem.
Yes, you can create migrations in beego now. Example, If you need to create a new table, you can start by creating a new migration file using the bee tool:
bee generate migration create_user_table
This command will create a file inside database/migrations folder. The file name contains the date, time and name of the migration.
For further details you can check this article https://ncona.com/2017/10/database-migrations-in-beego

Map existing Database table for Laravel

I am looking for a way to map existing tables in a project with the Eloquent ORM and use them in code. I use a MySQL database and plan to migrate to MSSQL. Any way points are appreciated.
You'll have to do this manually.
i.e., create an eloquent model for each of the tables you want access to in your code using eloquent.
If you don't have timestamps named created_at and updated_at, in your model you can disable those columns.
Manually
If you have a users table you could 'map' it with a user.php file in your models folder like this
class User extends Eloquent {
protected $table = 'users';
public $timestamps = false;
}
Via artisan
You can use Jeffrey Ways Laravel Generators to help streamline the initial creation of your models, however you'll still need to make the timestamp modification manually.
This looks like an old post, but it was edited a couple of days ago, so I don't know if the original author is looking for a solution again, but if someone needs this info, here is a packagist package for Laravel 5 to do what you are asking.
Laravel 5 model generator from existing schema:
https://packagist.org/packages/ignasbernotas/laravel-model-generator
Hope that helps someone!
There is also a Eloquent Model Generator library. It can be used for generating Eloquent models using database tables as a source. Generated model will include relation methods, docblocks for magic field and relations and several additional properties.
Another here: https://github.com/Xethron/migrations-generator.
You'll only want to use these generators for local development, so you don't want to update the production providers array in config/app.php. Instead, add the provider in app/Providers/AppServiceProvider.php.
For more details look here - https://packagist.org/packages/ignasbernotas/laravel-model-generator#user-content-installation
You can also use SQL Server Migration Assistant (SSMA) to port the database to SQL Server, but you will still need to write your own models to match the schema.
http://blogs.msdn.com/b/ssma/
http://www.microsoft.com/en-us/download/details.aspx?id=43688
Still this might help get halfway there, from both sides of the puzzle.

Sqlite3 Adding Columns

I'm working with Django and I added a new model variable meaning that I need another column in my sqlite3 data base.
I have heard that I'm supposed to use sqlite> , but I am really confused when I start to use it. So, if that is part of the solution, can you be very specific on what to do?
thanks
MORE INFO:
my app is called "livestream" & and my class is "Stream"
I added the model "channel"
returns ---->
DatabaseError: table livestream_stream has no column named channel
You can ALTER TABLE to add a new column in Sqlite3 but not rename it nor drop it. Sqlite3 is a very useful database for bootstrapping your app. But sooner or later, you will need to change to a more robust/flexible database engine, say MySql or Postgresql.
Every time you add a new column to your models using Sqlite, you will need to recreate the schema (as far as I know, when you do migrations with Sqlite to add new columns, south complaints. see below). An approach I like more is use MySql with Django-South from the beginning, where I'm not sure about every aspect of my database.
Django South is an app for doing database migrations. It's very useful and the docs are a good starting point for beginners.
Every time you should make modifications to your database, you should consider them as migrations and use South.
Hope this helps!

Using liquibase, how to handle an object model that is a subset of database table

Some days I love my dba's, and then there is today...
In a Grails app, we use the database-migration plugin (based on Liquibase) to handle migrations etc.
All works lovely.
I have been informed that there is a set of db administrative meta data that we must support on every table. This information has zero use to the app.
Now, I can easily update my models to accommodate this. But that answer is ugly.
The problem is now at each migration, Liquibase/database-migration plugin, complains about the schema and the model being out of sync.
Is there anyway to tell Liquibase (or GORM) that columns x,y,z are to be ignored?
What I am trying to avoid is changesets like this:
changeSet(author: "cwright (generated)", id: "1333733941347-5") {
dropColumn(columnName: "BUILD_MONTH", tableName: "ASSIGNMENT") }
Which tries to bring the schema back in line with the model. Being able to annotate those columns as not applying to the model would be a good thing.
Sadly, you're probably better off defining your own mapping block and taking control of the Data Mapper (what Hibernate essentially is) yourself at this point. If you need to take control of the way the database-integration plugin handles migrations, you might wanna look at the source or raise an issue on the JIRA. Naively, mapping your columns explicitly in the domain model should allow you to bypass unnecessary columns from the DB.

How do you make your model's database portable in CakePHP?

I'm not very familiar with cake.. So here's my questions.. we're developing an app on mysql, but it may eventually need to deploy to mssql or oracle. How do we make sure that we won't have strange problems with our primary keys? In mysql they are AUTO INCREMENT columns but IIRC in oracle you need to use sequences... is there a way to make this a transparent change? Am I over thinking it?
Does anyone have experience with switching database vendors on a cakephp app? any pointers or things to keep an eye out for?
In the Cake database config file you choose your driver (see http://book.cakephp.org/view/40/Database-Configuration). Then, if you set your PK (which will also be your A_I column if using MySQL) with the fieldname id, Cake will automatically handle the auto_increment insertion. I would presume (NB: haven't tried Cake w/ something else) that Cake will take care of A_I columns in something like Oracle.
Cake uses its own DB abstraction layer -- but the included abstractions cover quite a bit, and it will perform as specified (i.e. it'll handle your auto increment stuff for you).
In short, you're probably overthinking. That said, I would mock up a little cake app, then try switching databases behind it (change your db config and your app should automagically switch over).
HTH,
Travis
The following practices work great for me
I use cake schemas ( I tend to set up 1 schema file for each group of models. I.E. User, Role, Profile might all be in one UsersSchema file )
Also take a look at using the debuggable.com FixturesShell - it allows you to import test case fixtures into the live database. Great for setting up that initial group of users and roles from the schema file.
Also, if you set your 'id' field to VARCHAR(36) instead of INT(#) cake will automatically use UUID style id's. This means you have a FAR FAR lower chance of your data having id value collisions if you need to move the data to another application or server.
The fixtures shell also has a command line tool for generating uuids ( so you can add them to your $records variable in the fixture for insertion etc. )
In summary - Use the CakeSchema schemas shell, the fixtures shell from debuggable.com and UUID values for your id's and it should give you a portable structure creation tool, a portable data insertion tool, and a portable id field format.
http://github.com/felixge/debuggable-scraps/tree/fd0e5ad625cb21f5ba16e6b186821a5774089ac7/cakephp/shells/fixtures
http://api.cakephp.org/class/schema-shell
You need to be using "cake schema" to manage your DB.. This will handle all the DB specific stuff when you create your database.
http://book.cakephp.org/view/735/Generating-and-using-Schema-files

Resources