I have a table in Postgres with DDL like this one:
CREATE TABLE robots(
robot_id INTEGER NOT NULL CONSTRAINT robot_id_pkey PRIMARY KEY,
name TEXT
);
I know I can insert a record with following SQL statement:
INSERT INTO robots (robot_id, name) VALUES (nextval('robots_seq'), 'WALL-E');
I need to make CRUD operations in Phalcon for this table. Also I want to use ORM features.
So I do:
$robot = new Robots();
$robot->setRobotId(new \Phalcon\Db\RawValue("nextval('robots_seq')"));
$robot->setName('WALL-E');
$robot->save();
And get the following exception:
Uncaught PDOException: SQLSTATE[22P02]: Invalid text representation:
7 ERROR: invalid input syntax for integer: 'nextval('robots_seq')';
Is there any way to accomplish this ?
To tell Phalcon what is name of your model sequence use function getSequenceName:
public function getSequenceName() {
return 'category_id_seq';
}
Phalcon assumes that your models with serial (auto increment) columns will have a sequence named [table_name]_[column_name]_seq.
In your case, in order to make Phalcon take care of handling auto increment columns you should have a sequence named robots_robot_id_seq instead of robots_seq for the column robot_id (which I'd call just "id", by the way).
This way you do not have to worry about setting the id when creating an object and after saving Phalcon will fill that field automatically for you:
CREATE TABLE robots(
robot_id SERIAL PRIMARY KEY NOT NULL,
name TEXT
);
$robot = new Robots();
$robot->setName('WALL-E');
$robot->save();
$robot->getRobotId(); // Should return last "nextval()" sequence
Hope it helps.
Related
I've got some code like this:
$this->validate(new \Phalcon\Mvc\Model\Validator\Uniqueness(['field' => $field]));
if (true == $this->validationHasFailed()) {
throw new SpecialInternalUniqueException();
}
This works for all columns except for natural Primary Keys. That is, Primary Keys that are not surrogate keys (auto-incrementing integers). For example, in the job_titles table, the natural key column is "job_title" - which, in our case, refers to the name of the job title. This name should be unique, and I want to be able to check for that in the code prior to saving. However, Phalcon happily ignores it, somehow.
I'm actually setting up a unit test for this right now and doing something similar to the following:
$job_title = new JobTitles();
$job_title->job_title = 'Unique Test';
$job_title->description = 'Desc A';
$job_title->save();
$job_title2 = new JobTitles();
$job_title2->job_title = 'Unique Test';
$job_title->description = 'Desc B';
$job_title->save();
The exception never gets thrown. What ends up in the database is a single column for the first Unique test with Desc A, and no record for the second one. But I don't get a thrown exception.
Any thoughts?
EDIT:
Also, I've tried with the ->create() function in place of the save() function.
First you should be aware that in the default behavior those validations are created from the actual database schema right after the model class is initialized; you're not supposed to add them manually in that case.
In other words, the default meta-data strategy for models is the Database Introspection Strategy
So a exception will only be raised if the job_title field is already indexed for uniqueness checking in the database scheme. If you aren't able to actually create this PK in the database, you may change the default meta-data strategy for your models and them set the metadata manually (sigh).
How can use PostgreSQL array_append() and array_remove() in Yii? I am trying to update array type attribute on following table rows-
CREATE TABLE Books(
id INT NOT NULL PRIMARY KEY,
name UUID[])
Sample data rows:
1 NULL
2 NULL
$books=Books::model()->findByPk($id);
$books->name='array_append(name, $Name_key_array)';
$books->save();
I have found following error:
CDbException
CDbCommand failed to execute the SQL statement: SQLSTATE[22P02]: Invalid text representation: 7 ERROR: array value must start with "{" or dimension information
But If I use array directly then its work but not when using variable name i.e.
array_append({1,2,3}, {4})
Also, I already tried few more ways but haven't found any success. I hope will find some great ideas to fix this issue.
I think you are using the array_append() in other way. it should be like this
SELECT array_append(ARRAY[1,2], 3);
array_append
--------------
{1,2,3}
(1 row)
So if i correct yours, it should be
$books->name='array_append($Name_key_array, name)';
for removing elements from an array, check this solution: http://www.youlikeprogramming.com/2013/06/removing-values-from-a-postgresql-array/
to an array in PostgreSQL data must be inserted in the following way,
INSERT INTO table (arr_col) VALUES ('{val1,val2, val3}');
http://www.postgresql.org/docs/9.1/static/arrays.html
I'd like RedBean to create unique keys/indexes when generating the schema. The following code does- opposed to how I understand the documentation- not do this:
R::setup('sqlite:rss_loader.db3');
$bean = R::findOne(IMG);
if (!$bean->id) {
$bean = R::dispense(IMG);
$bean->setMeta("buildcommand.unique.0", array('url'));
$bean->url = 'text';
R::store($bean);
$bean->wipe();
R::freeze(); //no more schema changes!
}
What is happening in sqlite ist this:
create table img (id integer primary key autoincrement, url)
What I was expecting was this:
create table img (id integer primary key autoincrement, url text unique)
Can this be achieved without write SQL against RedBean?
What version of Redbean are you using? It looks like they updated the buildcommand in the latest version. This is what the manual says:
$bean->setMeta("buildcommand.unique" , array(array($property1, $property2)));
Plugging in what you have:
$bean->setMeta("buildcommand.unique" , array(array('url')));
If that doesn't work, you may have to read the actual code under the setMeta function and see what is actually going on.
To do this on an existing table it is sufficient to "store" an empty bean like this- no data needs to be added to the DB:
$bean = R::dispense(IMG);
$bean->setMeta("buildcommand.unique", array(array(...)));
R::store($bean);
(Word of warning, if you freeze after doing this, you're not guaranteed to have all your columns)
I'm trying to store data into cassandra with it being ordered by time. Having trouble using the TimeUUIDType as the key.
I get the following error with phpcassa...
Fatal error: Uncaught exception 'cassandra_InvalidRequestException'
with message 'TimeUUID should be 16 or 0 bytes (6)'
This occurs when calling the insert method...
$pool = new ConnectionPool("Keyspace1", array("localhost:9160"));
$column_family = new ColumnFamily($pool, 'users');
$column_family->insert(CassandraUtil::uuid1(), array('name' => 'value'));
I created a test table using cassandra-cli with the following command...
CREATE COLUMN FAMILY users WITH comparator = TimeUUIDType;
comparator applies to column names, not row keys. If you want the row keys to be TimeUUIDs, you should set key_validation_class instead.
You're getting this exception because Cassandra is expecting a TimeUUID for the column name, but you're passing a normal string.
I'm trying to create a dynamic form builder. Therefore PHP gets a set of names from a database and creates a new table with those names as column names. This works quite well until one or more names are integer (for ex. '12345'). Then the script fails.
How can I force PHP of MySQL to give numeric table names?
Here is a piece of the code (its still a draft):
$slaop = 'id INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(id)';
require_once 'dbconnect.php';
$connector = new DbConnector();
$result = $connector->query( 'SELECT * FROM '.$form.' ORDER BY rang' );
while ($opslaan = $connector->fetchArray($result)){
$slaop .= ', ';
$slaop .= $opslaan['tekstid'];
$slaop .= ' TEXT';
}
echo $slaop;
// OPSLAAN
$formnaam = $_GET['welkform'];
require_once 'dbconnectsave.php';
$connector = new DbConnectorSave();
$connector->query('CREATE TABLE '.$formnaam.'('.$slaop.')')
or die(mysql_error());
$opslaan['tekstid']; is the part where the text of integer are called.
Does anyone have an idea?
Why not prefix all tables with the form name? Then integers don't matter...
As others have noted, this may not be a good idea.
However, you can still do it if the column name is surrounded in backticks. Here's a couple of MySQL examples:
create table abc (id int, 123 int); -- fails
create table abc (id int, `123` int); -- succeeds
How can i force php of mysql to give numeric table names?
May be you can force your application not to use such field names?
And also change the whole design as well, without employing dynamically created tables, and use more usual approach of storing table structure in some table?
Use a prefix that starts with a letter for your column names.